* #40116: Switch to 2.3.0 libzrtpcpp version
diff --git a/jni/libzrtp/sources/.gitignore b/jni/libzrtp/sources/.gitignore
index 4876ff9..ee3d613 100644
--- a/jni/libzrtp/sources/.gitignore
+++ b/jni/libzrtp/sources/.gitignore
@@ -1,4 +1,4 @@
-build*/
+build/
autoconf/
doc/html/
configure
@@ -16,8 +16,4 @@
*.pc
*.spec
*~
-.DS_Store
-._.DS_Store
-._buildmac
-.directory
diff --git a/jni/libzrtp/sources/CMakeLists.txt b/jni/libzrtp/sources/CMakeLists.txt
index 8e0bb80..847717c 100755
--- a/jni/libzrtp/sources/CMakeLists.txt
+++ b/jni/libzrtp/sources/CMakeLists.txt
@@ -12,53 +12,13 @@
PROJECT(libzrtpcpp)
-SET(CPACK_PACKAGE_VERSION_MAJOR 4)
-SET(CPACK_PACKAGE_VERSION_MINOR 1)
-SET(CPACK_PACKAGE_VERSION_PATCH 1)
+SET(CPACK_PACKAGE_VERSION_MAJOR 2)
+SET(CPACK_PACKAGE_VERSION_MINOR 3)
+SET(CPACK_PACKAGE_VERSION_PATCH 0)
-set (VERSION 4.1.1)
-set (SOVERSION 4)
-
-# Define supported command line parameters.
-#
-# Example to build the tivi client: cmake -DTIVI=true ..
-# Without any options cmake generates libzrtpcpp for use with GNU ccRTP
-#
-option(CCRTP "Build library to use with GNU ccRTP." OFF)
-option(CORE_LIB "Build core library only, no spcific client support." OFF)
-option(CRYPTO_STANDALONE "Use embedded crypto and big number modules." ON)
-option(TIVI "Build library for the tivi client, implies '-DCRYPTO_STNDALONE=true'." OFF)
-option(SQLITE "Use SQLite DB as backend for ZRTP cache." OFF)
-option(SDES "Include SDES when not building for CCRTP." ON)
-
-option(ANDROID "Generate Android makefiles (Android.mk)" ON)
-option(JAVA "Generate Java support files (requires JDK and SWIG)" OFF)
-
-
-# **** Check what and how to build ****
-#
-if (CCRTP AND TIVI)
- MESSAGE(FATAL_ERROR "Cannot build more than one client at once. Use different build directories.")
-endif()
-
-if (CCRTP)
- set (PACKAGE libzrtpcpp)
- set(zrtplibName zrtpcpp)
-elseif (TIVI)
- set (PACKAGE libzrtptivi)
- set(zrtplibName zrtptivi)
- set(CRYPTO_STANDALONE true)
- set(SQLITE true)
-elseif (CORE_LIB)
- set (PACKAGE libzrtpcore)
- set(zrtplibName zrtpcppcore)
-else()
- MESSAGE(WARNING "No client defined, building for GNU ccRTP.")
- set (PACKAGE libzrtpcpp)
- set(CCRTP true)
- set(zrtplibName zrtpcpp)
-endif()
-
+set (VERSION 2.3.0)
+set (SOVERSION 2)
+set (PACKAGE libzrtpcpp)
if(MSVC60)
set(BUILD_STATIC ON CACHE BOOL "static linking only" FORCE)
@@ -68,18 +28,26 @@
endif()
# set to true for debug and trace during CMakeLists development
-# set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_VERBOSE_MAKEFILE FALSE)
-execute_process(COMMAND git rev-parse --short HEAD OUTPUT_VARIABLE GIT_COMMIT)
-STRING(REGEX REPLACE "(\r?\n)+$" "" GIT_COMMIT "${GIT_COMMIT}")
-
-MESSAGE( STATUS "Configuring GNU ${PROJECT_NAME} ${VERSION} for ${PACKAGE}, commit: ${GIT_COMMIT} ...")
+MESSAGE( STATUS "Configuring GNU ${PROJECT_NAME} ${VERSION}...")
# include most of the fine stuff we need
+include(cmake/Modules/FindGcryptConfig.cmake)
include(FindPkgConfig)
include(CheckLibraryExists)
include(CheckIncludeFiles)
-include(CheckFunctionExists)
+include(cmake/Modules/AutoArgs.cmake)
+
+if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
+ include(cmake/Modules/GeneratePackage.cmake)
+
+ GENERATE_PACKAGING(${PACKAGE} ${VERSION})
+endif()
+
+# check the -Denable-ccrtp setting, defaults to true
+enable_arg(ccrtp true "Enable GNU ccRTP support for GNU ZRTP")
+args_help()
if (NOT LIB_SUFFIX)
set(LIBDIRNAME "lib")
@@ -93,171 +61,107 @@
set(LIBDIRNAME "lib${LIB_SUFFIX}")
endif()
+# setup the Thread include and lib
+find_package(Threads)
+if(CMAKE_HAVE_PTHREAD_H)
+ set(HAVE_PTHREAD_H TRUE)
+endif()
+set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT})
+
+# define the name of the lib. zrtpcppcore does not include the ccRTP stuff.
+set(zrtplib zrtpcppcore)
+if(enable_ccrtp)
+ if (USES_CCRTP_INCLUDE_DIRS)
+ message(STATUS " Using local commoncpp dependency")
+ else()
+ find_package(PkgConfig)
+ pkg_check_modules(USES_CCRTP libccrtp>=2.0.0)
+ endif()
+ include_directories(${USES_CCRTP_INCLUDE_DIRS})
+ link_directories(${USES_CRTP_LIBRARY_DIRS})
+ add_definitions(${USES_CCRTP_CFLAGS})
+ set (LIBS ${LIBS} ${USES_CCRTP_LDFLAGS} ${USES_CCRTP_LIBRARIES})
+ set(zrtplib zrtpcpp)
+endif()
+
+# now get info about crypto libraries
+gcr_check(GCRYPT gcrypt)
+#if(GCRYPT_FOUND)
+# check_include_files(gcrypt.h HAVE_GCRYPT_H)
+# set(LIBS ${LIBS} ${GCRYPT_LIBRARIES})
+# set(BUILD_REQ "libgcrypt-devel")
+# set(CRYPTOBACKEND="")
+# set(PACKAGE_REQ "libgcrypt")
+#else()
+ pkg_check_modules(OPENSSL libcrypto>=0.9.8)
+ if (OPENSSL_FOUND)
+ set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS}) #update include files search directory
+ check_include_files(openssl/bn.h HAVE_OPENSSL_BN_H)
+ check_include_files(openssl/aes.h HAVE_OPENSSL_AES_H)
+ check_include_files(openssl/sha.h HAVE_OPENSSL_SHA_H)
+ check_library_exists(crypto EVP_CipherInit_ex "${OPENSSL_LIBDIR}" HAVE_SSL_CRYPT) #use search lib directory from pkg-config
+ set(LIBS ${LIBS} -lcrypto)
+ set(CRYPTOBACKEND "libcrypto >= 0.9.8")
+ set(BUILD_REQ "libopenssl-devel >= 0.9.8")
+ set(PACKAGE_REQ "libopenssl >= 0.9.8")
+ include_directories(${OPENSSL_INCLUDE_DIRS}) #update includes directory from pkg-config
+ else()
+ message(FATAL_ERROR "No crypto library found")
+ endif()
+#endif()
+
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(string.h HAVE_STRING_H)
-if (NOT CRYPTO_STANDALONE)
- pkg_check_modules(OPENSSL libcrypto>=0.9.8)
- if (OPENSSL_FOUND)
- set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS}) #update include files search directory
- check_include_files(openssl/bn.h HAVE_OPENSSL_BN_H)
- check_include_files(openssl/aes.h HAVE_OPENSSL_AES_H)
- check_include_files(openssl/sha.h HAVE_OPENSSL_SHA_H)
- check_library_exists(crypto EVP_CipherInit_ex "${OPENSSL_LIBDIR}" HAVE_SSL_CRYPT) #use search lib directory from pkg-config
- set(LIBS ${LIBS} -lcrypto)
- set(CRYPTOBACKEND "libcrypto >= 0.9.8")
- set(BUILD_REQ "libopenssl-devel >= 0.9.8")
- set(PACKAGE_REQ "libopenssl >= 0.9.8")
- include_directories(${OPENSSL_INCLUDE_DIRS}) #update includes directory from pkg-config
- else()
- message(FATAL_ERROR "No crypto library found")
- endif()
-else()
- # For crypto standalone mode we need to configure the bnlib. In a first step
- # without the tests and demos.
- check_include_files(stdint.h HAVE_STDINT_H)
- check_include_files(stdint.h HAVE_ASSERT_H)
- check_include_files(limits.h HAVE_LIMITS_H)
+# necessary and required modules checked, ready to generate config.h
+configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
- check_function_exists(memmove HAVE_MEMMOVE)
- check_function_exists(memcpy HAVE_MEMCPY)
+# the following set(...) commands are only to have backward
+# compatibility with autoconf stuff to generate the pc file
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix ${prefix}/bin)
+set(libdir ${prefix}/${LIBDIRNAME})
+set(includedir ${prefix}/include)
+set(PACKAGE pkgconfig)
+configure_file(libzrtpcpp.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplib}.pc @ONLY)
- # TODO: check if we compile the tests for bnlib
- #
- # check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
- # check_function_exists(getrusage HAVE_GETRUSAGE)
- # check_function_exists(clock HAVE_CLOCK)
- # check_function_exists(time HAVE_TIME)
+configure_file(libzrtpcpp.spec.cmake ${CMAKE_CURRENT_BINARY_DIR}/libzrtpcpp.spec @ONLY)
- # Check if Solaris-style gethrvtime() is available
- # check_function_exists(gethrvtime HAVE_GETHRVTIME)
- #
- # until here
-
- # necessary and required modules checked, ready to generate config.h
- configure_file(${CMAKE_SOURCE_DIR}/bnlib/bnconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/bnconfig.h)
-endif()
-
-if (SQLITE)
- pkg_check_modules(SQLITE3 sqlite3>=3.7)
- if (SQLITE3_FOUND)
- check_include_files(sqlite3.h HAVE_SQLITE_H)
- set(LIBS ${LIBS} -lsqlite3)
- else()
- message(FATAL_ERROR "SQLite3 library not found")
- endif()
-endif()
-
-# necessary and required modules checked, ready to generate config.h in top-level build directory
-configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
+#to make sure includes are first taken from those directory
+include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
add_definitions(-g -O2 -fno-strict-aliasing)
if(CMAKE_COMPILER_IS_GNUCXX)
-# add_definitions(-Wno-long-long -Wno-char-subscripts)
-# add_definitions(-Wall -ansi -pedantic)
-# add_definitions(-Wall -pedantic)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -std=c99")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -std=c++11")
- add_definitions(-DNEW_STDCPP)
+ add_definitions(-Wno-long-long -Wno-char-subscripts)
+ add_definitions(-Wall -ansi -pedantic)
+ add_definitions(-DNEW_STDCPP)
endif()
-include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/zrtp)
+add_subdirectory(src)
-if(CRYPTO_STANDALONE)
- add_definitions(-DSUPPORT_NON_NIST)
- include_directories (${CMAKE_SOURCE_DIR}/bnlib)
-endif()
-
-if (SDES AND NOT CCRTP)
- set (sdes_src ${CMAKE_SOURCE_DIR}/zrtp/ZrtpSdesStream.cpp)
-endif()
-
-# **** The following source files a common for all clients ****
-#
-set(zrtp_src_no_cache
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCallbackWrapper.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZRtp.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCrc32.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketCommit.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketConf2Ack.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketConfirm.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketDHPart.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketGoClear.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketClearAck.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketHelloAck.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketHello.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketError.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketErrorAck.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketPingAck.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketPing.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketSASrelay.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketRelayAck.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpStateClass.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpTextData.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpConfigure.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCWrapper.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/Base32.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/zrtpB64Encode.c
- ${CMAKE_SOURCE_DIR}/zrtp/zrtpB64Decode.c
- ${CMAKE_SOURCE_DIR}/common/osSpecifics.c ${sdes_src})
-
-set(bnlib_src
- ${CMAKE_SOURCE_DIR}/bnlib/bn00.c
- ${CMAKE_SOURCE_DIR}/bnlib/lbn00.c
- ${CMAKE_SOURCE_DIR}/bnlib/bn.c
- ${CMAKE_SOURCE_DIR}/bnlib/lbnmem.c
- ${CMAKE_SOURCE_DIR}/bnlib/sieve.c
- ${CMAKE_SOURCE_DIR}/bnlib/prime.c
- ${CMAKE_SOURCE_DIR}/bnlib/bnprint.c
- ${CMAKE_SOURCE_DIR}/bnlib/jacobi.c
- ${CMAKE_SOURCE_DIR}/bnlib/germain.c
- ${CMAKE_SOURCE_DIR}/bnlib/ec/ec.c
- ${CMAKE_SOURCE_DIR}/bnlib/ec/ecdh.c
- ${CMAKE_SOURCE_DIR}/bnlib/ec/curve25519-donna.c)
-
-set(zrtp_skein_src
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/skeinMac256.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/skein256.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/skeinMac384.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/skein384.cpp)
-
-set(zrtp_crypto_src
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/zrtpDH.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/hmac256.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha256.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/hmac384.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha384.cpp
-
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/aesCFB.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/twoCFB.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha2.c)
-
-if (NOT SQLITE)
- set(zrtp_src ${zrtp_src_no_cache}
- ${CMAKE_SOURCE_DIR}/zrtp/ZIDCacheFile.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZIDRecordFile.cpp)
-else()
- set(zrtp_src ${zrtp_src_no_cache}
- ${CMAKE_SOURCE_DIR}/zrtp/ZIDCacheDb.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/ZIDRecordDb.cpp
- ${CMAKE_SOURCE_DIR}/zrtp/zrtpCacheSqliteBackend.c)
-
-endif()
-
-if (CCRTP)
- add_subdirectory(clients/ccrtp)
+if (enable_ccrtp)
add_subdirectory(demo)
endif()
-if (TIVI)
- add_subdirectory(clients/tivi)
+if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package/)
+ MESSAGE(STATUS "package dir not found")
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/)
endif()
-if (CORE_LIB)
- add_subdirectory(clients/no_client)
-endif()
+########### install files ###############
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplib}.pc DESTINATION ${LIBDIRNAME}/pkgconfig)
+if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
+
+ ########### Add uninstall target ###############
+ configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+ add_custom_target(uninstall
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+endif()
##very usefull for macosx, specially when using gtkosx bundler
if(APPLE)
if (NOT CMAKE_INSTALL_NAME_DIR)
diff --git a/jni/libzrtp/sources/COPYING b/jni/libzrtp/sources/COPYING
index 02bbb60..4432540 100644
--- a/jni/libzrtp/sources/COPYING
+++ b/jni/libzrtp/sources/COPYING
@@ -1,165 +1,676 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
+ Preamble
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
- 0. Additional Definitions.
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
- 1. Exception to Section 3 of the GNU GPL.
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
+ The precise terms and conditions for copying, distribution and
+modification follow.
- 2. Conveying Modified Versions.
+ TERMS AND CONDITIONS
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
+ 0. Definitions.
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
+ "This License" refers to version 3 of the GNU General Public License.
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
- 3. Object Code Incorporating Material from Library Header Files.
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
- 4. Combined Works.
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
+ 1. Source Code.
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
- d) Do one of the following:
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
+ The Corresponding Source for a work in source code form is that
+same work.
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
+ 2. Basic Permissions.
- 5. Combined Libraries.
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
- 6. Revised Versions of the GNU Lesser General Public License.
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
+ 4. Conveying Verbatim Copies.
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
\ No newline at end of file
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/jni/libzrtp/sources/NEWS b/jni/libzrtp/sources/NEWS
index f2b72e6..6224923 100755
--- a/jni/libzrtp/sources/NEWS
+++ b/jni/libzrtp/sources/NEWS
@@ -1,128 +1,3 @@
-== GNU ZRTP 4.1.1 ==
-
-Is a bug fix release that fixes some problems when building a standalone
-version of the library, i.e. with embedded crypto algorithms and not using
-on openSSL.
-
-Another fix was necessary for NetBSD thread handling.
-
-
-== GNU ZRTP 4.1.0 ==
-
-Small enhancements when dealing with non-NIST algorithms. An application may
-set a ''algorithm selection policy'' to control the selection behaviour. In
-addition the the standrad selection policy (as per RFC6189) this version
-provides a _non-NIST_ selection policy: if the selected public key algorithm
-is a non-NIST ECC algorithm then the other selection functions prefer non-NIST
-HASH algorithms (Skein etc).
-
-
-== GNU ZRTP 4.0.0 ==
-
-For this version I added some new algorithms for the DH key agreement
-and the Skein Hash for ZRTP. Not further functional enhancments.
-
-Added a new (old) build parameter -DCORE_LIB that will build a ZRTP core
-library. This was available in V2.3 but I somehow lost this for 3.0
-You may add other build parameters, such as SQLITE and CRYPTO_STANDALONE
-if you build the core library.
-
-
-== GNU ZRTP 3.2.0 ==
-
-The main ZRTP modules contain fixes for three vulnerabilities found by Mark
-Dowd. Thus we advise application developers to use this version of the
-library. The vulnerabilities may lead to application crashes during ZRTP
-negotiation if an attacker sends prepared ZRTP packets. The fixes remove these
-attack vectors.
-
-Some small other enhancements and cleanup, mainly inside client code.
-
-Some enhancements in cache handling and the handling of retained shared
-secrets. This change was proposed by Phil, is a slight security enhacement and
-is fully backward comaptible.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-For details please refer to the Git logs.
-
-
-== GNU ZRTP 3.1.0 ==
-
-This version adds some new features and code that supports some other
-client and this accounts for the most changes inside this release.
-
-The ZRTP core functionality was not changed as much (bug fixes, cleanup
-mainly) and remains fully backward compatible with older library
-versions. However, one nice enhancement was done: the addition of a standalone
-SDES support module. This module supports basic SDES only without the fancy
-stuff like many other SDES implementations. Thus it's pretty interoperable.
-
-Some other features are:
-- add some android support for a client, may serve as template for others
-- documentation and code cleanup
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-
-== GNU ZRTP 3.0.0 ==
-
-This is a major enhancement and restructuring of the overall ZRTP
-distribution. This was necessary because more and more other clients use ZRTP
-and add their specific glue code. Also some clients are not prepared to use
-openSSL or other crypto libraries to their code and distributions.
-
-Here a summary of the changes
-- a new directory layout to accomodate various clients
-- add standalone crypto modules, for example for AES, to have a real
- standalone ZRTP/SRTP library that does not require any other crypto library
- (optional via CMake configuration)
-- Re-structure ZRTP cache and add SQlite3 as optional storage backend
-
-The default settings for CMake build the normal ZRTP library that use openSSL
-as crypto backend, use the normal file based cache and include the GNU ccRTP
-modules. This is a librray that is to a large degree compatible with the
-earlier builds.
-
-Please refer to the top level CMakeFile.txt for options how to switch on the
-standalone crypto mode or the SQlite3 based cache storage.
-
-
-== GNU ZRTP 2.3.0 ==
-
-Add a "paranoid" mode to ZRTP. If and applications switches to this mode then
-the ZRTP stack _always_ asks the user to confirm the SAS thus ZRTP behaves as
-if it does not have a cache to store the retained secrets. However, setting
-the paranoid mode does not diable the cache, only the GUI behaviour.
-
-Enhance the CMake scripts to build a ZRTP library that does not contain GNU
-ccRTP modules and does not require ccRTP dependencies.
-
-== GNU ZRTP 2.2.0 ==
-
-Add stubs, callbacks and other provisions to prepare the full implementation
-of the SAS signing feature, see RFC6189, section 7.2. This feature needs
-support from applications and is rarely used if at all.
-
-As usual smaller fixes, code clean up etc.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-== GNU ZRTP 2.1.2 ==
-
-The main topic of this release was to add SRTCP support and some missing
-optional features of ZRTP.
-
-As such I've added some new API and classes that applications may use to add
-SRTCP or to use the new ZRTP features. the ZRTP stack now supports PBX
-handling, refer to RFC6189 section 7.3ff.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
== GNU ZRTP 2.0.0 ==
Modify some files to use the new uCommon/commoncpp libraries instead
@@ -275,7 +150,7 @@
The method ''setOtherSecret(...)'' was renamed to ''setPbxSecret(...)''
to reflect the modification in the draft.
-The method ''setSrtpsSecret(...)'' was renamed to ''setAuxSecret(...)''
+The methos ''setSrtpsSecret(...)'' is was renamed to ''setAuxSecret(...)''
to reflect the modification in the draft.
diff --git a/jni/libzrtp/sources/README.md b/jni/libzrtp/sources/README.md
index f7b9966..cac0592 100644
--- a/jni/libzrtp/sources/README.md
+++ b/jni/libzrtp/sources/README.md
@@ -1,49 +1,29 @@
## GNU ZRTP C++
This package provides a library that adds ZRTP support to the GNU
-ccRTP stack and serves as library for other RTP stacks (PJSIP, GStreamer).
-Phil Zimmermann developed ZRTP to allow ad-hoc, easy to
+ccRTP stack. Phil Zimmermann developed ZRTP to allow ad-hoc, easy to
use key negotiation to setup Secure RTP (SRTP) sessions. GNU ZRTP works
together with GNU ccRTP (1.5.0 or later) and provides a ZRTP
implementation that can be directly embedded into client and server
applications.
-The GNU ZRTP implementation is compliant to [RFC 6189][] and adds some more
-algorithms. Currently GNU ZRTP C++ supports the following features:
+The GNU ZRTP implementation is compliant to [RFC 6189][]. Currently GNU ZRTP
+C++ supports the following features:
* multi-stream mode
-* Finite field Diffie-Hellman with 2048 and 3072 bit primes
-* Elliptic curve Diffie-Hellman with 256 and 384 bit curves (NIST curves)
-* Elliptic curves Curve25519 and Curve3617 (Dan Bernstein, Tanja Lange)
-* Skein Hash and MAC for ZRTP
-* AES-128 and AES-256 symmetric ciphers
+* Finite field Diffie-Helman with 2048 and 3072 bit primes
+* Elliptic curve Diffie-Helman with 256 and 384 bit curves
+* AES-128 and AES-256 symmetric cipher
* Twofish-128 and Twofish-256 bit symmetric ciphers
* The SRTP authentication methods HMAC-SHA1 with 32 bit and 80 bit length and
the Skein MAC with 32 bit and 64 bit length
* The Short Authentication String (SAS) type with base 32 encoding (4
- characters) and the SAS 256 type using words.
+ characters)
-Some features like preshared mode are not supported but the GNU
-ZRTP C++ implementation defines the necessary external interfaces and
-functions for these enhanced features.
-
-**Note:** The Elliptic curves Cure25519 and Curve3617 are available only if you
-select the crypto standalone mode during build.
-
-The newer verisons (starting with 4.1) implement an extensible mechanisms to
-define algorithm selection policies that control selection of Hash, symmetric
-cipher, and the SRTP authentication. Currently two policies exist: _Standard_
-and _PreferNonNist_. The Standard policy selects algorihms based on the
-preferences (order) in the Hello packet, the PreferNonNist policy prefers
-non-NIST algorithms, for example Skein and Twofish, if the selected public key
-(Diffie-Hellman) algorithm is also one of the non-NIST algorithms. This is
-fully backward compatible and in-line with RFC6189.
-
-### SDES support
-This release also provides SDES support. The SDES implementation does not
-support all of the fancy stuff but is usable in most cases. This implementation
-however supports the new SDES crypto mixing to overcome some security issues
-for SIP forking. Please look for `draft-zimmermann-mmusic-sdesc-mix-00`.
+Enhanced features like PBX SAS relay aka *trusted Man-in-the-Middle* or
+preshared mode are not supported but the GNU ZRTP C++ implementation defines
+the necessary external interfaces and functions for these enhanced features
+(stubs only).
### Interoperability
During the development of ZRTP and its sister implementation ZRTP4J (the Java
@@ -68,7 +48,7 @@
functionality to C based RTP implementations. The first use of the ZRTP C
wrapper was for the [PJSIP][] library, actually the RTP part of this
library. The ZRTP handler for PJSIP is [here][pjzrtp]. This port enables PJSIP
-based clients to use ZRTP. One of the first clients that uses this feature is
+based clients to use ZRTP. One of the first clients that use this feature is
*[CSipSimple][]*, an very good open source Android SIP client.
[pjsip]: http://www.pjsip.org
@@ -91,21 +71,13 @@
### License and further information
-I changed the license of the ZRTP core source files from GPL to LGPL. Other
-sources files may have own license. Please refer to the copyright notices of
-the files.
-
-Thus most of this library is licensed under the GNU LGPL, version 3 or later.
+Please note, this library is licensed under the GNU GPL, version 3 or
+later, and has been copyright assigned to the Free Software Foundation.
For further information refer to the [ZRTP FAQ][zrtpfaq] and the
[GNU ZRTP howto][zrtphow]. Both are part of the GNU Telephony wiki and are
located in its documentation category.
-Source code in the directory `clients/tivi` and below is not licensed under the
-GNU LGPL and is for reference and review only. Refer to the copyright statments
-of the source code in these directories, in particular the sqlite3 sources which
-have their own license.
-
[zrtphow]: http://www.gnutelephony.org/index.php/GNU_ZRTP_How_To
[zrtpfaq]: http://www.gnutelephony.org/index.php/ZRTP_FAQ
[rfc 6189]: http://tools.ietf.org/html/rfc6189
@@ -117,23 +89,11 @@
the source archive or pulled the source from [Github][]:
cd <zrtpsrc_dir>
- mkdir build
- cd build
- cmake ..
- make
-
-The CMakeLists.txt supports several options. If you don't specify any options
-then `cmake` generates the build that supports GNU ccRTP library and it uses
-the standalone cryptographic modules, thus no it's not necessary to install an
-cryptographic library on the system. Optionally you may configure ZRTP to use
-_sqlite3_ instead of a simple file to store the ZRTP cache data. For example
-
- cmake -DSQLITE=true ..
-
-creates the build files that use _sqlite3_.
-
-Please have a look at the `CMakeLists.txt` for other options.
-
+ mkdir build
+ cd build
+ cmake ..
+ make
+
Running cmake in a separate `build` directory is the preferred way. Cmake and
the following `make` generate all files in or below the build directory. Thus
the base directory and the source directories are not polluted with `*.o`,
@@ -143,13 +103,3 @@
different settings without mixing the two builds.
[github]: http://github.com/wernerd/ZRTPCPP
-
-
-### Notes when building ZRTP C++ for Android
-
-The CMake files support creation of an `Android.mk` file for the Tivi client
-and may give you an idea how to do it for other clients. The generated
-`Android.mk` generates `buildinfo_*.c` files in the root directory. You may
-delete these files after the Android static libraries are ready.
-
-Since version 4.1.1 the example Android build files require NDK r9c.
diff --git a/jni/libzrtp/sources/bnlib/bn.c b/jni/libzrtp/sources/bnlib/bn.c
deleted file mode 100644
index 36d07fc..0000000
--- a/jni/libzrtp/sources/bnlib/bn.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * bn.c - the high-level bignum interface
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#include <bn.h>
-
-/* Functions */
-void
-bnBegin(struct BigNum *bn)
-{
- static int bninit = 0;
-
- if (!bninit) {
- bnInit();
- bninit = 1;
- }
-
- bn->ptr = 0;
- bn->size = 0;
- bn->allocated = 0;
-}
-
-void
-bnSwap(struct BigNum *a, struct BigNum *b)
-{
- void *p;
- unsigned t;
-
- p = a->ptr;
- a->ptr = b->ptr;
- b->ptr = p;
-
- t = a->size;
- a->size = b->size;
- b->size = t;
-
- t = a->allocated;
- a->allocated = b->allocated;
- b->allocated = t;
-}
-
-int (*bnYield)(void);
-
-void (*bnEnd)(struct BigNum *bn);
-int (*bnPrealloc)(struct BigNum *bn, unsigned bits);
-int (*bnCopy)(struct BigNum *dest, struct BigNum const *src);
-void (*bnNorm)(struct BigNum *bn);
-void (*bnExtractBigBytes)(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len);
-int (*bnInsertBigBytes)(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-void (*bnExtractLittleBytes)(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len);
-int (*bnInsertLittleBytes)(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-unsigned (*bnLSWord)(struct BigNum const *src);
-int (*bnReadBit)(struct BigNum const *bn, unsigned bit);
-unsigned (*bnBits)(struct BigNum const *src);
-int (*bnAdd)(struct BigNum *dest, struct BigNum const *src);
-int (*bnSub)(struct BigNum *dest, struct BigNum const *src);
-int (*bnCmpQ)(struct BigNum const *a, unsigned b);
-int (*bnSetQ)(struct BigNum *dest, unsigned src);
-int (*bnAddQ)(struct BigNum *dest, unsigned src);
-int (*bnSubQ)(struct BigNum *dest, unsigned src);
-int (*bnCmp)(struct BigNum const *a, struct BigNum const *b);
-int (*bnSquare)(struct BigNum *dest, struct BigNum const *src);
-int (*bnMul)(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int (*bnMulQ)(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int (*bnDivMod)(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d);
-int (*bnMod)(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *d);
-unsigned (*bnModQ)(struct BigNum const *src, unsigned d);
-int (*bnExpMod)(struct BigNum *result, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod);
-int (*bnDoubleExpMod)(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod);
-int (*bnTwoExpMod)(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod);
-int (*bnGcd)(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int (*bnInv)(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod);
-int (*bnLShift)(struct BigNum *dest, unsigned amt);
-void (*bnRShift)(struct BigNum *dest, unsigned amt);
-unsigned (*bnMakeOdd)(struct BigNum *n);
-int (*bnBasePrecompBegin)(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits);
-int (*bnBasePrecompCopy)(struct BnBasePrecomp *dst,
- struct BnBasePrecomp const *src);
-void (*bnBasePrecompEnd)(struct BnBasePrecomp *pre);
-int (*bnBasePrecompExpMod)(struct BigNum *dest,
- struct BnBasePrecomp const *pre, struct BigNum const *exp,
- struct BigNum const *mod);
-int (*bnDoubleBasePrecompExpMod)(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn.h b/jni/libzrtp/sources/bnlib/bn.h
deleted file mode 100644
index 5cc80f0..0000000
--- a/jni/libzrtp/sources/bnlib/bn.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * bn.h - the interface to the bignum routines.
- * All functions which return ints can potentially allocate memory
- * and return -1 if they are unable to. All "const" arguments
- * are unmodified.
- *
- * This is not particularly asymmetric, as some operations are of the
- * form a = b @ c, while others do a @= b. In general, outputs may not
- * point to the same struct BigNums as inputs, except as specified
- * below. This relationship is referred to as "being the same as".
- * This is not numerical equivalence.
- *
- * The "Q" operations take "unsigned" inputs. Higher values of the
- * extra input may work on some implementations, but 65535 is the
- * highest portable value. Just because UNSIGNED_MAX is larger than
- * that, or you know that the word size of the library is larger than that,
- * that, does *not* mean it's allowed.
- */
-#ifndef BN_H
-#define BN_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-struct BigNum {
- void *ptr;
- unsigned size; /* Note: in (variable-sized) words */
- unsigned allocated;
-};
-
-#ifndef SWIG
-/*
- * User-supplied function: if non-NULL, this is called during long-running
- * computations. You may put Yield() calls in here to give CPU time to
- * other processes. You may also force the computation to be aborted,
- * by returning a value < 0, which will be the return value of the
- * bnXXX call. (You probably want the value to be someting other than
- * -1, to distinguish it from a n out-of-memory error.)
- *
- * The functions that this is called from, and the intervals at which it
- * is called, are not well defined, just "reasonably often". (Currently,
- * once per exponent bit in nodular exponentiation, and once per two
- * divisions in GCD and inverse computation.)
- */
-extern int (*bnYield)(void);
-
-/* Functions */
-
-/*
- * You usually never have to call this function explicitly, as
- * bnBegin() takes care of it. If the program jumps to address 0,
- * this function has bot been called.
- */
-void bnInit(void);
-
-/*
- * This initializes an empty struct BigNum to a zero value.
- * Do not use this on a BigNum which has had a value stored in it!
- */
-void bnBegin(struct BigNum *bn);
-
-/* Swap two BigNums. Cheap. */
-void bnSwap(struct BigNum *a, struct BigNum *b);
-
-/* Reset an initialized bigNum to empty, pending deallocation. */
-extern void (*bnEnd)(struct BigNum *bn);
-
-/*
- * If you know you'll need space in the number soon, you can use this function
- * to ensure that there is room for at least "bits" bits. Optional.
- * Returns <0 on out of memory, but the value is unaffected.
- */
-extern int (*bnPrealloc)(struct BigNum *bn, unsigned bits);
-
-/* Hopefully obvious. dest = src. dest may be the same as src. */
-extern int (*bnCopy)(struct BigNum *dest, struct BigNum const *src);
-
-/*
- * Mostly done automatically, but this removes leading zero words from
- * the internal representation of the BigNum. Use is unclear.
- */
-extern void (*bnNorm)(struct BigNum *bn);
-
-/*
- * Move bytes between the given buffer and the given BigNum encoded in
- * base 256. I.e. after either of these, the buffer will be equal to
- * (bn / 256^lsbyte) % 256^len. The difference is which is altered to
- * match the other!
- */
-extern void (*bnExtractBigBytes)(struct BigNum const *bn,
- unsigned char *dest, unsigned lsbyte, unsigned len);
-extern int (*bnInsertBigBytes)(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-
-/* The same, but the buffer is little-endian. */
-extern void (*bnExtractLittleBytes)(struct BigNum const *bn,
- unsigned char *dest, unsigned lsbyte, unsigned len);
-extern int (*bnInsertLittleBytes)(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-
-/* Return the least-significant bits (at least 16) of the BigNum */
-extern unsigned (*bnLSWord)(struct BigNum const *src);
-
-/* Return the selected bit of the BigNum (bit 0 is bn mod 2) */
-extern int (*bnReadBit)(struct BigNum const *bn, unsigned bit);
-
-/*
- * Return the number of significant bits in the BigNum.
- * 0 or 1+floor(log2(src))
- */
-extern unsigned (*bnBits)(struct BigNum const *src);
-#define bnBytes(bn) ((bnBits(bn)+7)/8)
-
-/*
- * dest += src. dest and src may be the same. Guaranteed not to
- * allocate memory unnecessarily, so if you're sure bnBits(dest)
- * won't change, you don't need to check the return value.
- */
-extern int (*bnAdd)(struct BigNum *dest, struct BigNum const *src);
-
-/*
- * dest -= src. dest and src may be the same, but bnSetQ(dest, 0) is faster.
- * if dest < src, returns +1 and sets dest = src-dest.
- */
-extern int (*bnSub)(struct BigNum *dest, struct BigNum const *src);
-
-/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmpQ(a, b) <=> 0 */
-extern int (*bnCmpQ)(struct BigNum const *a, unsigned b);
-
-/* dest = src, where 0 <= src < 2^16. */
-extern int (*bnSetQ)(struct BigNum *dest, unsigned src);
-
-/* dest += src, where 0 <= src < 2^16 */
-extern int (*bnAddQ)(struct BigNum *dest, unsigned src);
-
-/* dest -= src, where 0 <= src < 2^16 */
-extern int (*bnSubQ)(struct BigNum *dest, unsigned src);
-
-/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmp(a, b) <=> 0 */
-extern int (*bnCmp)(struct BigNum const *a, struct BigNum const *b);
-
-/* dest = src^2. dest may be the same as src, but it costs time. */
-extern int (*bnSquare)(struct BigNum *dest, struct BigNum const *src);
-
-/* dest = a * b. dest may be the same as a or b, but it costs time. */
-extern int (*bnMul)(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-
-/* dest = a * b, where 0 <= b < 2^16. dest and a may be the same. */
-extern int (*bnMulQ)(struct BigNum *dest, struct BigNum const *a, unsigned b);
-
-/*
- * q = n/d, r = n%d. r may be the same as n, but not d,
- * and q may not be the same as n or d.
- * re-entrancy issue: this temporarily modifies d, but restores
- * it for return.
- */
-extern int (*bnDivMod)(struct BigNum *q, struct BigNum *r,
- struct BigNum const *n, struct BigNum const *d);
-/*
- * dest = src % d. dest and src may be the same, but not dest and d.
- * re-entrancy issue: this temporarily modifies d, but restores
- * it for return.
- */
-extern int (*bnMod)(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *d);
-
-/* return src % d, where 0 <= d < 2^16. */
-extern unsigned int (*bnModQ)(struct BigNum const *src, unsigned d);
-
-/* n = n^exp, modulo "mod" "mod" *must* be odd */
-extern int (*bnExpMod)(struct BigNum *result, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod);
-
-/*
- * dest = n1^e1 * n2^e2, modulo "mod". "mod" *must* be odd.
- * dest may be the same as n1 or n2.
- */
-extern int (*bnDoubleExpMod)(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod);
-
-/* n = 2^exp, modulo "mod" "mod" *must* be odd */
-extern int (*bnTwoExpMod)(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod);
-
-/* dest = gcd(a, b). The inputs may overlap arbitrarily. */
-extern int (*bnGcd)(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-
-/* dest = src^-1, modulo "mod". dest may be the same as src. */
-extern int (*bnInv)(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod);
-
-/* Shift dest left "amt" places */
-extern int (*bnLShift)(struct BigNum *dest, unsigned amt);
-/* Shift dest right "amt" places, discarding low-order bits */
-extern void (*bnRShift)(struct BigNum *dest, unsigned amt);
-
-/* For the largest 2^k that divides n, divide n by it and return k. */
-extern unsigned (*bnMakeOdd)(struct BigNum *n);
-
-/*
- * Precomputed data for rapid base^exp (mod mod) computation with fixed
- * base and mod.
- */
-struct BnBasePrecomp {
- void *array; /* Ponter to array of pointers to words */
- unsigned msize; /* Words in modulis (normalized) */
- unsigned bits; /* Bits per array element */
- unsigned maxebits; /* Maximum exponent bits */
- unsigned entries; /* Number of entries */
- unsigned arraysize;
-};
-
-extern int (*bnBasePrecompBegin)(struct BnBasePrecomp *pre,
- struct BigNum const *base, struct BigNum const *mod,
- unsigned maxebits);
-extern void (*bnBasePrecompEnd)(struct BnBasePrecomp *pre);
-extern int (*bnBasePrecompExpMod)(struct BigNum *dest,
- struct BnBasePrecomp const *pre, struct BigNum const *exp,
- struct BigNum const *mod);
-extern int (*bnDoubleBasePrecompExpMod)(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod);
-#endif /* SWIF */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif/* !BN_H */
diff --git a/jni/libzrtp/sources/bnlib/bn00.c b/jni/libzrtp/sources/bnlib/bn00.c
deleted file mode 100644
index 4bc9797..0000000
--- a/jni/libzrtp/sources/bnlib/bn00.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * bn00.c - auto-size-detecting bn??.c file.
- *
- * Written in 1995 by Colin Plumb.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#include "bnsize00.h"
-
-#if BNSIZE64
-
-/* Include all of the C source file by reference */
-#include "bn64.c"
-#include "bninit64.c"
-
-#elif BNSIZE32
-
-/* Include all of the C source file by reference */
-#include "bn32.c"
-#include "bninit32.c"
-
-#else /* BNSIZE16 */
-
-/* Include all of the C source file by reference */
-#include "bn16.c"
-#include "bninit16.c"
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/bn16.c b/jni/libzrtp/sources/bnlib/bn16.c
deleted file mode 100644
index 98e5aa3..0000000
--- a/jni/libzrtp/sources/bnlib/bn16.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn16.c - the high-level bignum interface
- *
- * Like lbn16.c, this reserves the string "16" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it. DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn16.h"
-#include "lbnmem.h"
-#include "bn16.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h" /* For memmove() */
-
-/* Functions */
-void
-bnInit_16(void)
-{
- bnEnd = bnEnd_16;
- bnPrealloc = bnPrealloc_16;
- bnCopy = bnCopy_16;
- bnNorm = bnNorm_16;
- bnExtractBigBytes = bnExtractBigBytes_16;
- bnInsertBigBytes = bnInsertBigBytes_16;
- bnExtractLittleBytes = bnExtractLittleBytes_16;
- bnInsertLittleBytes = bnInsertLittleBytes_16;
- bnLSWord = bnLSWord_16;
- bnReadBit = bnReadBit_16;
- bnBits = bnBits_16;
- bnAdd = bnAdd_16;
- bnSub = bnSub_16;
- bnCmpQ = bnCmpQ_16;
- bnSetQ = bnSetQ_16;
- bnAddQ = bnAddQ_16;
- bnSubQ = bnSubQ_16;
- bnCmp = bnCmp_16;
- bnSquare = bnSquare_16;
- bnMul = bnMul_16;
- bnMulQ = bnMulQ_16;
- bnDivMod = bnDivMod_16;
- bnMod = bnMod_16;
- bnModQ = bnModQ_16;
- bnExpMod = bnExpMod_16;
- bnDoubleExpMod = bnDoubleExpMod_16;
- bnTwoExpMod = bnTwoExpMod_16;
- bnGcd = bnGcd_16;
- bnInv = bnInv_16;
- bnLShift = bnLShift_16;
- bnRShift = bnRShift_16;
- bnMakeOdd = bnMakeOdd_16;
- bnBasePrecompBegin = bnBasePrecompBegin_16;
- bnBasePrecompEnd = bnBasePrecompEnd_16;
- bnBasePrecompExpMod = bnBasePrecompExpMod_16;
- bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_16;
-}
-
-void
-bnEnd_16(struct BigNum *bn)
-{
- if (bn->ptr) {
- LBNFREE((BNWORD16 *)bn->ptr, bn->allocated);
- bn->ptr = 0;
- }
- bn->size = 0;
- bn->allocated = 0;
-
- MALLOCDB;
-}
-
-/* Internal function. It operates in words. */
-static int
-bnResize_16(struct BigNum *bn, unsigned len)
-{
- void *p;
-
- /* Round size up: most mallocs impose 8-byte granularity anyway */
- len = (len + (8/sizeof(BNWORD16) - 1)) & ~(8/sizeof(BNWORD16) - 1);
- p = LBNREALLOC((BNWORD16 *)bn->ptr, bn->allocated, len);
- if (!p)
- return -1;
- bn->ptr = p;
- bn->allocated = len;
-
- MALLOCDB;
-
- return 0;
-}
-
-#define bnSizeCheck(bn, size) \
- if (bn->allocated < size && bnResize_16(bn, size) < 0) \
- return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_16(struct BigNum *bn, unsigned bits)
-{
- bits = (bits + 16-1)/16;
- bnSizeCheck(bn, bits);
- MALLOCDB;
- return 0;
-}
-
-int
-bnCopy_16(struct BigNum *dest, struct BigNum const *src)
-{
- bnSizeCheck(dest, src->size);
- dest->size = src->size;
- lbnCopy_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, src->size);
- MALLOCDB;
- return 0;
-}
-
-/* Is this ever needed? Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_16(struct BigNum *bn)
-{
- bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes. Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_16(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (16 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len) {
- *dest++ = 0;
- len--;
- }
-
- if (len)
- lbnExtractBigBytes_16((BNWORD16 *)bn->ptr, dest, lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_16(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertBigBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes. Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_16(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (16 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len)
- dest[--len] = 0;
-
- if (len)
- lbnExtractLittleBytes_16((BNWORD16 *)bn->ptr, dest,
- lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_16(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertLittleBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_16(struct BigNum const *bn)
-{
- return bn->size ? (unsigned)((BNWORD16 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_16(struct BigNum const *bn, unsigned bit)
-{
- BNWORD16 word;
- if (bit/16 >= bn->size)
- return 0;
- word = ((BNWORD16 *)bn->ptr)[BIGLITTLE(-1-bit/16,bit/16)];
- return (int)(word >> (bit % 16) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_16(struct BigNum const *bn)
-{
- return lbnBits_16((BNWORD16 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_16(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD16 t;
-
- if (!s)
- return 0;
-
- bnSizeCheck(dest, s);
-
- if (d < s) {
- lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- t = lbnAddN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnAdd1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- bnSizeCheck(dest, d+1);
- ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
- dest->size = d+1;
- }
- }
- return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_16(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD16 t;
-
- if (d < s && d < (s = lbnNorm_16((BNWORD16 *)src->ptr, s))) {
- bnSizeCheck(dest, s);
- lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- if (!s)
- return 0;
- t = lbnSubN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnSub1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- lbnNeg_16((BNWORD16 *)dest->ptr, d);
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr,
- dest->size);
- MALLOCDB;
- return 1;
- }
- }
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size);
- return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_16(struct BigNum const *a, unsigned b)
-{
- unsigned t;
- BNWORD16 v;
-
- t = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
- /* If a is more than one word long or zero, it's easy... */
- if (t != 1)
- return (t > 1) ? 1 : (b ? -1 : 0);
- v = (unsigned)((BNWORD16 *)a->ptr)[BIGLITTLE(-1,0)];
- return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_16(struct BigNum *dest, unsigned src)
-{
- if (src) {
- bnSizeCheck(dest, 1);
-
- ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD16)src;
- dest->size = 1;
- } else {
- dest->size = 0;
- }
- return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_16(struct BigNum *dest, unsigned src)
-{
- BNWORD16 t;
-
- if (!dest->size)
- return bnSetQ(dest, src);
-
- t = lbnAdd1_16((BNWORD16 *)dest->ptr, dest->size, (BNWORD16)src);
- MALLOCDB;
- if (t) {
- src = dest->size;
- bnSizeCheck(dest, src+1);
- ((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
- dest->size = src+1;
- }
- return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_16(struct BigNum *dest, unsigned src)
-{
- BNWORD16 t;
-
- if (!dest->size)
- return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
- t = lbnSub1_16((BNWORD16 *)dest->ptr, dest->size, src);
- MALLOCDB;
- if (t) {
- /* Underflow. <= 1 word, so do it simply. */
- lbnNeg_16((BNWORD16 *)dest->ptr, 1);
- dest->size = 1;
- return 1;
- }
-/* Try to normalize? Needing this is going to be pretty damn rare. */
-/* dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size); */
- return 0;
-}
-
-/*
- * Compare two BigNums. Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_16(struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
-
- s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
- t = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
- if (s != t)
- return s > t ? 1 : -1;
- return lbnCmp_16((BNWORD16 *)a->ptr, (BNWORD16 *)b->ptr, s);
-}
-
-/* dest = src*src. This is more efficient than bnMul. */
-int
-bnSquare_16(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s;
- BNWORD16 *srcbuf;
-
- s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
- if (!s) {
- dest->size = 0;
- return 0;
- }
- bnSizeCheck(dest, 2*s);
-
- if (src == dest) {
- LBNALLOC(srcbuf, BNWORD16, s);
- if (!srcbuf)
- return -1;
- lbnCopy_16(srcbuf, (BNWORD16 *)src->ptr, s);
- lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)srcbuf, s);
- LBNFREE(srcbuf, s);
- } else {
- lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
- }
-
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, 2*s);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b. Any overlap between operands is allowed. */
-int
-bnMul_16(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
- BNWORD16 *srcbuf;
-
- s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
- t = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
- if (!s || !t) {
- dest->size = 0;
- return 0;
- }
-
- if (a == b)
- return bnSquare_16(dest, a);
-
- bnSizeCheck(dest, s+t);
-
- if (dest == a) {
- LBNALLOC(srcbuf, BNWORD16, s);
- if (!srcbuf)
- return -1;
- lbnCopy_16(srcbuf, (BNWORD16 *)a->ptr, s);
- lbnMul_16((BNWORD16 *)dest->ptr, srcbuf, s,
- (BNWORD16 *)b->ptr, t);
- LBNFREE(srcbuf, s);
- } else if (dest == b) {
- LBNALLOC(srcbuf, BNWORD16, t);
- if (!srcbuf)
- return -1;
- lbnCopy_16(srcbuf, (BNWORD16 *)b->ptr, t);
- lbnMul_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s,
- srcbuf, t);
- LBNFREE(srcbuf, t);
- } else {
- lbnMul_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s,
- (BNWORD16 *)b->ptr, t);
- }
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s+t);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_16(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
- unsigned s;
-
- s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
- if (!s || !b) {
- dest->size = 0;
- return 0;
- }
- if (b == 1)
- return bnCopy_16(dest, a);
- bnSizeCheck(dest, s+1);
- lbnMulN1_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s, b);
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s+1);
- MALLOCDB;
- return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_16(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d)
-{
- unsigned dsize, nsize;
- BNWORD16 qhigh;
-
- dsize = lbnNorm_16((BNWORD16 *)d->ptr, d->size);
- nsize = lbnNorm_16((BNWORD16 *)n->ptr, n->size);
-
- if (nsize < dsize) {
- q->size = 0; /* No quotient */
- r->size = nsize;
- return 0; /* Success */
- }
-
- bnSizeCheck(q, nsize-dsize);
-
- if (r != n) { /* You are allowed to reduce in place */
- bnSizeCheck(r, nsize);
- lbnCopy_16((BNWORD16 *)r->ptr, (BNWORD16 *)n->ptr, nsize);
- }
-
- qhigh = lbnDiv_16((BNWORD16 *)q->ptr, (BNWORD16 *)r->ptr, nsize,
- (BNWORD16 *)d->ptr, dsize);
- nsize -= dsize;
- if (qhigh) {
- bnSizeCheck(q, nsize+1);
- *((BNWORD16 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
- q->size = nsize+1;
- } else {
- q->size = lbnNorm_16((BNWORD16 *)q->ptr, nsize);
- }
- r->size = lbnNorm_16((BNWORD16 *)r->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* det = src % d */
-int
-bnMod_16(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
- unsigned dsize, nsize;
-
- nsize = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
- dsize = lbnNorm_16((BNWORD16 *)d->ptr, d->size);
-
-
- if (dest != src) {
- bnSizeCheck(dest, nsize);
- lbnCopy_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, nsize);
- }
-
- if (nsize < dsize) {
- dest->size = nsize; /* No quotient */
- return 0;
- }
-
- (void)lbnDiv_16((BNWORD16 *)dest->ptr BIGLITTLE(-dsize,+dsize),
- (BNWORD16 *)dest->ptr, nsize,
- (BNWORD16 *)d->ptr, dsize);
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_16(struct BigNum const *src, unsigned d)
-{
- unsigned s;
-
- s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
- if (!s)
- return 0;
-
- if (d & (d-1)) /* Not a power of 2 */
- d = lbnModQ_16((BNWORD16 *)src->ptr, s, d);
- else
- d = (unsigned)((BNWORD16 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
- return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_16(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned nsize, esize, msize;
-
- nsize = lbnNorm_16((BNWORD16 *)n->ptr, n->size);
- esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
- msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- /* Special-case base of 2 */
- if (nsize == 1 && ((BNWORD16 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
- if (lbnTwoExpMod_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)exp->ptr, esize,
- (BNWORD16 *)mod->ptr, msize) < 0)
- return -1;
- } else {
- if (lbnExpMod_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)n->ptr, nsize,
- (BNWORD16 *)exp->ptr, esize,
- (BNWORD16 *)mod->ptr, msize) < 0)
- return -1;
- }
-
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod). This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_16(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod)
-{
- unsigned n1size, e1size, n2size, e2size, msize;
-
- n1size = lbnNorm_16((BNWORD16 *)n1->ptr, n1->size);
- e1size = lbnNorm_16((BNWORD16 *)e1->ptr, e1->size);
- n2size = lbnNorm_16((BNWORD16 *)n2->ptr, n2->size);
- e2size = lbnNorm_16((BNWORD16 *)e2->ptr, e2->size);
- msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- if (lbnDoubleExpMod_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)n1->ptr, n1size, (BNWORD16 *)e1->ptr, e1size,
- (BNWORD16 *)n2->ptr, n2size, (BNWORD16 *)e2->ptr, e2size,
- (BNWORD16 *)mod->ptr, msize) < 0)
- return -1;
-
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_16(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod)
-{
- unsigned esize, msize;
-
- esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
- msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(n, msize);
-
- if (lbnTwoExpMod_16((BNWORD16 *)n->ptr, (BNWORD16 *)exp->ptr, esize,
- (BNWORD16 *)mod->ptr, msize) < 0)
- return -1;
-
- n->size = lbnNorm_16((BNWORD16 *)n->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_16(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- BNWORD16 *tmp;
- unsigned asize, bsize;
- int i;
-
- /* Kind of silly, but we might as well permit it... */
- if (a == b)
- return dest == a ? 0 : bnCopy(dest, a);
-
- /* Ensure a is not the same as "dest" */
- if (a == dest) {
- a = b;
- b = dest;
- }
-
- asize = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
- bsize = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
- bnSizeCheck(dest, bsize+1);
-
- /* Copy a to tmp */
- LBNALLOC(tmp, BNWORD16, asize+1);
- if (!tmp)
- return -1;
- lbnCopy_16(tmp, (BNWORD16 *)a->ptr, asize);
-
- /* Copy b to dest, if necessary */
- if (dest != b)
- lbnCopy_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)b->ptr, bsize);
- if (bsize > asize || (bsize == asize &&
- lbnCmp_16((BNWORD16 *)b->ptr, (BNWORD16 *)a->ptr, asize) > 0))
- {
- i = lbnGcd_16((BNWORD16 *)dest->ptr, bsize, tmp, asize,
- &dest->size);
- if (i > 0) /* Result in tmp, not dest */
- lbnCopy_16((BNWORD16 *)dest->ptr, tmp, dest->size);
- } else {
- i = lbnGcd_16(tmp, asize, (BNWORD16 *)dest->ptr, bsize,
- &dest->size);
- if (i == 0) /* Result in tmp, not dest */
- lbnCopy_16((BNWORD16 *)dest->ptr, tmp, dest->size);
- }
- LBNFREE(tmp, asize+1);
- MALLOCDB;
- return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod). Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_16(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod)
-{
- unsigned s, m;
- int i;
-
- s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
- m = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
- /* lbnInv_16 requires that the input be less than the modulus */
- if (m < s ||
- (m==s && lbnCmp_16((BNWORD16 *)src->ptr, (BNWORD16 *)mod->ptr, s)))
- {
- bnSizeCheck(dest, s + (m==s));
- if (dest != src)
- lbnCopy_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)src->ptr, s);
- /* Pre-reduce modulo the modulus */
- (void)lbnDiv_16((BNWORD16 *)dest->ptr BIGLITTLE(-m,+m),
- (BNWORD16 *)dest->ptr, s,
- (BNWORD16 *)mod->ptr, m);
- s = lbnNorm_16((BNWORD16 *)dest->ptr, m);
- MALLOCDB;
- } else {
- bnSizeCheck(dest, m+1);
- if (dest != src)
- lbnCopy_16((BNWORD16 *)dest->ptr,
- (BNWORD16 *)src->ptr, s);
- }
-
- i = lbnInv_16((BNWORD16 *)dest->ptr, s, (BNWORD16 *)mod->ptr, m);
- if (i == 0)
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, m);
-
- MALLOCDB;
- return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_16(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
- BNWORD16 carry;
-
- if (amt % 16) {
- carry = lbnLshift_16((BNWORD16 *)dest->ptr, s, amt % 16);
- if (carry) {
- s++;
- bnSizeCheck(dest, s);
- ((BNWORD16 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
- }
- }
-
- amt /= 16;
- if (amt) {
- bnSizeCheck(dest, s+amt);
- memmove((BNWORD16 *)dest->ptr BIGLITTLE(-s-amt, +amt),
- (BNWORD16 *)dest->ptr BIG(-s),
- s * sizeof(BNWORD16));
- lbnZero_16((BNWORD16 *)dest->ptr, amt);
- s += amt;
- }
- dest->size = s;
- MALLOCDB;
- return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_16(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
-
- if (amt >= 16) {
- memmove(
- (BNWORD16 *)dest->ptr BIG(-s+amt/16),
- (BNWORD16 *)dest->ptr BIGLITTLE(-s, +amt/16),
- (s-amt/16) * sizeof(BNWORD16));
- s -= amt/16;
- amt %= 16;
- }
-
- if (amt)
- (void)lbnRshift_16((BNWORD16 *)dest->ptr, s, amt);
-
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s);
- MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted. n = d * 2^s. Replaces n with d and returns s.
- * Returns 0 when given 0. (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_16(struct BigNum *n)
-{
- unsigned size;
- unsigned s; /* shift amount */
- BNWORD16 *p;
- BNWORD16 t;
-
- p = (BNWORD16 *)n->ptr;
- size = lbnNorm_16(p, n->size);
- if (!size)
- return 0;
-
- t = BIGLITTLE(p[-1],p[0]);
- s = 0;
-
- /* See how many words we have to shift */
- if (!t) {
- /* Shift by words */
- do {
- s++;
- BIGLITTLE(--p,p++);
- } while ((t = BIGLITTLE(p[-1],p[0])) == 0);
- size -= s;
- s *= 16;
- memmove((BNWORD16 *)n->ptr BIG(-size), p BIG(-size),
- size * sizeof(BNWORD16));
- p = (BNWORD16 *)n->ptr;
- MALLOCDB;
- }
-
- assert(t);
-
- if (!(t & 1)) {
- /* Now count the bits */
- do {
- t >>= 1;
- s++;
- } while ((t & 1) == 0);
-
- /* Shift the bits */
- lbnRshift_16(p, size, s & (16-1));
- /* Renormalize */
- if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
- --size;
- }
- n->size = size;
-
- MALLOCDB;
- return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn16.c for the details on how the algorithm works. Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired. To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- *
- * This implementation allows only power-of-2 values for "order". Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 160 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- *
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order). (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At 2 bits, order 2 uses 0.000000 multiplies
- * At 4 bits, order 2 uses 1.000000 multiplies
- * At 8 bits, order 2 uses 3.000000 multiplies
- * At 1_6 bits, order 2 uses 7.000000 multiplies
- * At 3_2 bits, order 2 uses 15.000000 multiplies
- * At 34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At 6_4 bits, order 4 uses 27.000000 multiplies
- * At 99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At 128 bits, order 8 uses 48.500000 multiplies
- * At 256 bits, order 8 uses 85.875000 multiplies
- * At 280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At 512 bits, order 1_6 uses 147.000000 multiplies
- * At 785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At 1024 bits, order 3_2 uses 257.562500 multiplies
- * At 2048 bits, order 3_2 uses 456.093750 multiplies
- * At 2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At 4096 bits, order 6_4 uses 795.281250 multiplies
- * At 5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At 8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_16(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits)
-{
- int i;
- BNWORD16 **array; /* Array of precomputed powers of base */
- unsigned n; /* Number of entries in array (needed) */
- unsigned m; /* Number of entries in array (non-NULL) */
- unsigned arraysize; /* Number of entries in array (allocated) */
- unsigned bits; /* log2(order) */
- unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
- static unsigned const bnBasePrecompThreshTable[] = {
- 33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
- };
-
- /* Clear pre in case of failure */
- pre->array = 0;
- pre->msize = 0;
- pre->bits = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-
- /* Find the correct bit-window size */
- bits = 0;
- do
- bits++;
- while (maxebits > bnBasePrecompThreshTable[bits]);
-
- /* Now the number of precomputed values we need */
- n = (maxebits+bits-1)/bits;
- assert(n*bits >= maxebits);
-
- arraysize = n+1; /* Add one trailing NULL for safety */
- array = lbnMemAlloc(arraysize * sizeof(*array));
- if (!array)
- return -1; /* Out of memory */
-
- /* Now allocate the entries (precomputed powers of base) */
- for (m = 0; m < n; m++) {
- BNWORD16 *entry;
-
- LBNALLOC(entry, BNWORD16, msize);
- if (!entry)
- break;
- array[m] = entry;
- }
-
- /* "m" is the number of successfully allocated entries */
- if (m < n) {
- /* Ran out of memory; see if we can use a smaller array */
- BNWORD16 **newarray;
-
- if (m < 2) {
- n = 0; /* Forget it */
- } else {
- /* How few bits can we use with what's allocated? */
- bits = (maxebits + m - 1) / m;
-retry:
- n = (maxebits + bits - 1) / bits;
- if (! (n >> bits) )
- n = 0; /* Not enough to amount to anything */
- }
- /* Free excess allocated array entries */
- while (m > n) {
- BNWORD16 *entry = array[--m];
- LBNFREE(entry, msize);
- }
- if (!n) {
- /* Give it up */
- lbnMemFree(array, arraysize * sizeof(*array));
- return -1;
- }
- /*
- * Try to shrink the pointer array. This might fail, but
- * it's not critical. lbnMemRealloc isn't guarnateed to
- * exist, so we may have to allocate, copy, and free.
- */
-#ifdef lbnMemRealloc
- newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
- (n+1) * sizeof(*array));
- if (newarray) {
- array = newarray;
- arraysize = n+1;
- }
-#else
- newarray = lbnMemAlloc((n+1) * sizeof(*array));
- if (newarray) {
- memcpy(newarray, array, n * sizeof(*array));
- lbnMemFree(array, arraysize * sizeof(*array));
- array = newarray;
- arraysize = n+1;
- }
-#endif
- }
-
- /* Pad with null pointers */
- while (m < arraysize)
- array[m++] = 0;
-
- /* Okay, we have our array, now initialize it */
- i = lbnBasePrecompBegin_16(array, n, bits,
- (BNWORD16 *)base->ptr, base->size,
- (BNWORD16 *)mod->ptr, msize);
- if (i < 0) {
- /* Ack, still out of memory */
- bits++;
- m = n;
- goto retry;
- }
- /* Finally, totoal success */
- pre->array = array;
- pre->bits = bits;
- pre->msize = msize;
- pre->maxebits = n * bits;
- pre->arraysize = arraysize;
- pre->entries = n;
- return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_16(struct BnBasePrecomp *pre)
-{
- BNWORD16 **array = pre->array;
-
- if (array) {
- unsigned entries = pre->entries;
- unsigned msize = pre->msize;
- unsigned m;
-
- for (m = 0; m < entries; m++) {
- BNWORD16 *entry = array[m];
- if (entry)
- LBNFREE(entry, msize);
- }
- lbnMemFree(array, pre->arraysize * sizeof(array));
- }
- pre->array = 0;
- pre->bits = 0;
- pre->msize = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_16(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
- unsigned esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
- BNWORD16 const * const *array = pre->array;
- int i;
-
- assert(msize == pre->msize);
- assert(((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_16((BNWORD16 *)exp->ptr, esize) <= pre->maxebits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnBasePrecompExp_16(dest->ptr, array, pre->bits,
- exp->ptr, esize, mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
- return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_16(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
- unsigned e1size = lbnNorm_16((BNWORD16 *)exp1->ptr, exp1->size);
- unsigned e2size = lbnNorm_16((BNWORD16 *)exp1->ptr, exp2->size);
- BNWORD16 const * const *array1 = pre1->array;
- BNWORD16 const * const *array2 = pre2->array;
- int i;
-
- assert(msize == pre1->msize);
- assert(msize == pre2->msize);
- assert(((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_16((BNWORD16 *)exp1->ptr, e1size) <= pre1->maxebits);
- assert(lbnBits_16((BNWORD16 *)exp2->ptr, e2size) <= pre2->maxebits);
- assert(pre1->bits == pre2->bits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnDoubleBasePrecompExp_16(dest->ptr, pre1->bits, array1,
- exp1->ptr, e1size, array2, exp2->ptr, e2size,
- mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
- return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn16.h b/jni/libzrtp/sources/bnlib/bn16.h
deleted file mode 100644
index 967d45a..0000000
--- a/jni/libzrtp/sources/bnlib/bn16.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn16.h - interface to 16-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_16(void);
-void bnEnd_16(struct BigNum *bn);
-int bnPrealloc_16(struct BigNum *bn, unsigned bits);
-int bnCopy_16(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_16(struct BigNum *a, struct BigNum *b);
-void bnNorm_16(struct BigNum *bn);
-void bnExtractBigBytes_16(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_16(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_16(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_16(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-unsigned bnLSWord_16(struct BigNum const *src);
-int bnReadBit_16(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_16(struct BigNum const *src);
-int bnAdd_16(struct BigNum *dest, struct BigNum const *src);
-int bnSub_16(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_16(struct BigNum const *a, unsigned b);
-int bnSetQ_16(struct BigNum *dest, unsigned src);
-int bnAddQ_16(struct BigNum *dest, unsigned src);
-int bnSubQ_16(struct BigNum *dest, unsigned src);
-int bnCmp_16(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_16(struct BigNum *dest, struct BigNum const *src);
-int bnMul_16(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnMulQ_16(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_16(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d);
-int bnMod_16(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *d);
-unsigned bnModQ_16(struct BigNum const *src, unsigned d);
-int bnExpMod_16(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_16(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod);
-int bnTwoExpMod_16(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod);
-int bnGcd_16(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnInv_16(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod);
-int bnLShift_16(struct BigNum *dest, unsigned amt);
-void bnRShift_16(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_16(struct BigNum *n);
-int bnBasePrecompBegin_16(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_16(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_16(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_16(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn32.c b/jni/libzrtp/sources/bnlib/bn32.c
deleted file mode 100644
index ee0d257..0000000
--- a/jni/libzrtp/sources/bnlib/bn32.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn32.c - the high-level bignum interface
- *
- * Like lbn32.c, this reserves the string "32" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it. DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn32.h"
-#include "lbnmem.h"
-#include "bn32.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h" /* For memmove() */
-
-/* Functions */
-void
-bnInit_32(void)
-{
- bnEnd = bnEnd_32;
- bnPrealloc = bnPrealloc_32;
- bnCopy = bnCopy_32;
- bnNorm = bnNorm_32;
- bnExtractBigBytes = bnExtractBigBytes_32;
- bnInsertBigBytes = bnInsertBigBytes_32;
- bnExtractLittleBytes = bnExtractLittleBytes_32;
- bnInsertLittleBytes = bnInsertLittleBytes_32;
- bnLSWord = bnLSWord_32;
- bnReadBit = bnReadBit_32;
- bnBits = bnBits_32;
- bnAdd = bnAdd_32;
- bnSub = bnSub_32;
- bnCmpQ = bnCmpQ_32;
- bnSetQ = bnSetQ_32;
- bnAddQ = bnAddQ_32;
- bnSubQ = bnSubQ_32;
- bnCmp = bnCmp_32;
- bnSquare = bnSquare_32;
- bnMul = bnMul_32;
- bnMulQ = bnMulQ_32;
- bnDivMod = bnDivMod_32;
- bnMod = bnMod_32;
- bnModQ = bnModQ_32;
- bnExpMod = bnExpMod_32;
- bnDoubleExpMod = bnDoubleExpMod_32;
- bnTwoExpMod = bnTwoExpMod_32;
- bnGcd = bnGcd_32;
- bnInv = bnInv_32;
- bnLShift = bnLShift_32;
- bnRShift = bnRShift_32;
- bnMakeOdd = bnMakeOdd_32;
- bnBasePrecompBegin = bnBasePrecompBegin_32;
- bnBasePrecompEnd = bnBasePrecompEnd_32;
- bnBasePrecompExpMod = bnBasePrecompExpMod_32;
- bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_32;
-}
-
-void
-bnEnd_32(struct BigNum *bn)
-{
- if (bn->ptr) {
- LBNFREE((BNWORD32 *)bn->ptr, bn->allocated);
- bn->ptr = 0;
- }
- bn->size = 0;
- bn->allocated = 0;
-
- MALLOCDB;
-}
-
-/* Internal function. It operates in words. */
-static int
-bnResize_32(struct BigNum *bn, unsigned len)
-{
- void *p;
-
- /* Round size up: most mallocs impose 8-byte granularity anyway */
- len = (len + (8/sizeof(BNWORD32) - 1)) & ~(8/sizeof(BNWORD32) - 1);
- p = LBNREALLOC((BNWORD32 *)bn->ptr, bn->allocated, len);
- if (!p)
- return -1;
- bn->ptr = p;
- bn->allocated = len;
-
- MALLOCDB;
-
- return 0;
-}
-
-#define bnSizeCheck(bn, size) \
- if (bn->allocated < size && bnResize_32(bn, size) < 0) \
- return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_32(struct BigNum *bn, unsigned bits)
-{
- bits = (bits + 32-1)/32;
- bnSizeCheck(bn, bits);
- MALLOCDB;
- return 0;
-}
-
-int
-bnCopy_32(struct BigNum *dest, struct BigNum const *src)
-{
- bnSizeCheck(dest, src->size);
- dest->size = src->size;
- lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, src->size);
- MALLOCDB;
- return 0;
-}
-
-/* Is this ever needed? Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_32(struct BigNum *bn)
-{
- bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes. Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_32(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (32 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len) {
- *dest++ = 0;
- len--;
- }
-
- if (len)
- lbnExtractBigBytes_32((BNWORD32 *)bn->ptr, dest, lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_32(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertBigBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes. Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_32(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (32 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len)
- dest[--len] = 0;
-
- if (len)
- lbnExtractLittleBytes_32((BNWORD32 *)bn->ptr, dest,
- lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_32(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertLittleBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_32(struct BigNum const *bn)
-{
- return bn->size ? (unsigned)((BNWORD32 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_32(struct BigNum const *bn, unsigned bit)
-{
- BNWORD32 word;
- if (bit/32 >= bn->size)
- return 0;
- word = ((BNWORD32 *)bn->ptr)[BIGLITTLE(-1-bit/32,bit/32)];
- return (int)(word >> (bit % 32) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_32(struct BigNum const *bn)
-{
- return lbnBits_32((BNWORD32 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_32(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD32 t;
-
- if (!s)
- return 0;
-
- bnSizeCheck(dest, s);
-
- if (d < s) {
- lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- t = lbnAddN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnAdd1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- bnSizeCheck(dest, d+1);
- ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
- dest->size = d+1;
- }
- }
- return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_32(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD32 t;
-
- if (d < s && d < (s = lbnNorm_32((BNWORD32 *)src->ptr, s))) {
- bnSizeCheck(dest, s);
- lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- if (!s)
- return 0;
- t = lbnSubN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnSub1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- lbnNeg_32((BNWORD32 *)dest->ptr, d);
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr,
- dest->size);
- MALLOCDB;
- return 1;
- }
- }
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size);
- return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_32(struct BigNum const *a, unsigned b)
-{
- unsigned t;
- BNWORD32 v;
-
- t = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
- /* If a is more than one word long or zero, it's easy... */
- if (t != 1)
- return (t > 1) ? 1 : (b ? -1 : 0);
- v = (unsigned)((BNWORD32 *)a->ptr)[BIGLITTLE(-1,0)];
- return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_32(struct BigNum *dest, unsigned src)
-{
- if (src) {
- bnSizeCheck(dest, 1);
-
- ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD32)src;
- dest->size = 1;
- } else {
- dest->size = 0;
- }
- return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_32(struct BigNum *dest, unsigned src)
-{
- BNWORD32 t;
-
- if (!dest->size)
- return bnSetQ(dest, src);
-
- t = lbnAdd1_32((BNWORD32 *)dest->ptr, dest->size, (BNWORD32)src);
- MALLOCDB;
- if (t) {
- src = dest->size;
- bnSizeCheck(dest, src+1);
- ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
- dest->size = src+1;
- }
- return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_32(struct BigNum *dest, unsigned src)
-{
- BNWORD32 t;
-
- if (!dest->size)
- return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
- t = lbnSub1_32((BNWORD32 *)dest->ptr, dest->size, src);
- MALLOCDB;
- if (t) {
- /* Underflow. <= 1 word, so do it simply. */
- lbnNeg_32((BNWORD32 *)dest->ptr, 1);
- dest->size = 1;
- return 1;
- }
-/* Try to normalize? Needing this is going to be pretty damn rare. */
-/* dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size); */
- return 0;
-}
-
-/*
- * Compare two BigNums. Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_32(struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
-
- s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
- t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
- if (s != t)
- return s > t ? 1 : -1;
- return lbnCmp_32((BNWORD32 *)a->ptr, (BNWORD32 *)b->ptr, s);
-}
-
-/* dest = src*src. This is more efficient than bnMul. */
-int
-bnSquare_32(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s;
- BNWORD32 *srcbuf;
-
- s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
- if (!s) {
- dest->size = 0;
- return 0;
- }
- bnSizeCheck(dest, 2*s);
-
- if (src == dest) {
- LBNALLOC(srcbuf, BNWORD32, s);
- if (!srcbuf)
- return -1;
- lbnCopy_32(srcbuf, (BNWORD32 *)src->ptr, s);
- lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)srcbuf, s);
- LBNFREE(srcbuf, s);
- } else {
- lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
- }
-
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, 2*s);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b. Any overlap between operands is allowed. */
-int
-bnMul_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
- BNWORD32 *srcbuf;
-
- s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
- t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
- if (!s || !t) {
- dest->size = 0;
- return 0;
- }
-
- if (a == b)
- return bnSquare_32(dest, a);
-
- bnSizeCheck(dest, s+t);
-
- if (dest == a) {
- LBNALLOC(srcbuf, BNWORD32, s);
- if (!srcbuf)
- return -1;
- lbnCopy_32(srcbuf, (BNWORD32 *)a->ptr, s);
- lbnMul_32((BNWORD32 *)dest->ptr, srcbuf, s,
- (BNWORD32 *)b->ptr, t);
- LBNFREE(srcbuf, s);
- } else if (dest == b) {
- LBNALLOC(srcbuf, BNWORD32, t);
- if (!srcbuf)
- return -1;
- lbnCopy_32(srcbuf, (BNWORD32 *)b->ptr, t);
- lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
- srcbuf, t);
- LBNFREE(srcbuf, t);
- } else {
- lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
- (BNWORD32 *)b->ptr, t);
- }
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+t);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_32(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
- unsigned s;
-
- s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
- if (!s || !b) {
- dest->size = 0;
- return 0;
- }
- if (b == 1)
- return bnCopy_32(dest, a);
- bnSizeCheck(dest, s+1);
- lbnMulN1_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s, b);
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+1);
- MALLOCDB;
- return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_32(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d)
-{
- unsigned dsize, nsize;
- BNWORD32 qhigh;
-
- dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
- nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
-
- if (nsize < dsize) {
- q->size = 0; /* No quotient */
- r->size = nsize;
- return 0; /* Success */
- }
-
- bnSizeCheck(q, nsize-dsize);
-
- if (r != n) { /* You are allowed to reduce in place */
- bnSizeCheck(r, nsize);
- lbnCopy_32((BNWORD32 *)r->ptr, (BNWORD32 *)n->ptr, nsize);
- }
-
- qhigh = lbnDiv_32((BNWORD32 *)q->ptr, (BNWORD32 *)r->ptr, nsize,
- (BNWORD32 *)d->ptr, dsize);
- nsize -= dsize;
- if (qhigh) {
- bnSizeCheck(q, nsize+1);
- *((BNWORD32 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
- q->size = nsize+1;
- } else {
- q->size = lbnNorm_32((BNWORD32 *)q->ptr, nsize);
- }
- r->size = lbnNorm_32((BNWORD32 *)r->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* det = src % d */
-int
-bnMod_32(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
- unsigned dsize, nsize;
-
- nsize = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
- dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
-
-
- if (dest != src) {
- bnSizeCheck(dest, nsize);
- lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, nsize);
- }
-
- if (nsize < dsize) {
- dest->size = nsize; /* No quotient */
- return 0;
- }
-
- (void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-dsize,+dsize),
- (BNWORD32 *)dest->ptr, nsize,
- (BNWORD32 *)d->ptr, dsize);
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_32(struct BigNum const *src, unsigned d)
-{
- unsigned s;
-
- s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
- if (!s)
- return 0;
-
- if (d & (d-1)) /* Not a power of 2 */
- d = lbnModQ_32((BNWORD32 *)src->ptr, s, d);
- else
- d = (unsigned)((BNWORD32 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
- return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_32(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned nsize, esize, msize;
-
- nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
- esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
- msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- /* Special-case base of 2 */
- if (nsize == 1 && ((BNWORD32 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
- if (lbnTwoExpMod_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)exp->ptr, esize,
- (BNWORD32 *)mod->ptr, msize) < 0)
- return -1;
- } else {
- if (lbnExpMod_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)n->ptr, nsize,
- (BNWORD32 *)exp->ptr, esize,
- (BNWORD32 *)mod->ptr, msize) < 0)
- return -1;
- }
-
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod). This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_32(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod)
-{
- unsigned n1size, e1size, n2size, e2size, msize;
-
- n1size = lbnNorm_32((BNWORD32 *)n1->ptr, n1->size);
- e1size = lbnNorm_32((BNWORD32 *)e1->ptr, e1->size);
- n2size = lbnNorm_32((BNWORD32 *)n2->ptr, n2->size);
- e2size = lbnNorm_32((BNWORD32 *)e2->ptr, e2->size);
- msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- if (lbnDoubleExpMod_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)n1->ptr, n1size, (BNWORD32 *)e1->ptr, e1size,
- (BNWORD32 *)n2->ptr, n2size, (BNWORD32 *)e2->ptr, e2size,
- (BNWORD32 *)mod->ptr, msize) < 0)
- return -1;
-
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_32(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod)
-{
- unsigned esize, msize;
-
- esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
- msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(n, msize);
-
- if (lbnTwoExpMod_32((BNWORD32 *)n->ptr, (BNWORD32 *)exp->ptr, esize,
- (BNWORD32 *)mod->ptr, msize) < 0)
- return -1;
-
- n->size = lbnNorm_32((BNWORD32 *)n->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- BNWORD32 *tmp;
- unsigned asize, bsize;
- int i;
-
- /* Kind of silly, but we might as well permit it... */
- if (a == b)
- return dest == a ? 0 : bnCopy(dest, a);
-
- /* Ensure a is not the same as "dest" */
- if (a == dest) {
- a = b;
- b = dest;
- }
-
- asize = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
- bsize = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
- bnSizeCheck(dest, bsize+1);
-
- /* Copy a to tmp */
- LBNALLOC(tmp, BNWORD32, asize+1);
- if (!tmp)
- return -1;
- lbnCopy_32(tmp, (BNWORD32 *)a->ptr, asize);
-
- /* Copy b to dest, if necessary */
- if (dest != b)
- lbnCopy_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)b->ptr, bsize);
- if (bsize > asize || (bsize == asize &&
- lbnCmp_32((BNWORD32 *)b->ptr, (BNWORD32 *)a->ptr, asize) > 0))
- {
- i = lbnGcd_32((BNWORD32 *)dest->ptr, bsize, tmp, asize,
- &dest->size);
- if (i > 0) /* Result in tmp, not dest */
- lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
- } else {
- i = lbnGcd_32(tmp, asize, (BNWORD32 *)dest->ptr, bsize,
- &dest->size);
- if (i == 0) /* Result in tmp, not dest */
- lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
- }
- LBNFREE(tmp, asize+1);
- MALLOCDB;
- return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod). Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_32(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod)
-{
- unsigned s, m;
- int i;
-
- s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
- m = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
- /* lbnInv_32 requires that the input be less than the modulus */
- if (m < s ||
- (m==s && lbnCmp_32((BNWORD32 *)src->ptr, (BNWORD32 *)mod->ptr, s)))
- {
- bnSizeCheck(dest, s + (m==s));
- if (dest != src)
- lbnCopy_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)src->ptr, s);
- /* Pre-reduce modulo the modulus */
- (void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-m,+m),
- (BNWORD32 *)dest->ptr, s,
- (BNWORD32 *)mod->ptr, m);
- s = lbnNorm_32((BNWORD32 *)dest->ptr, m);
- MALLOCDB;
- } else {
- bnSizeCheck(dest, m+1);
- if (dest != src)
- lbnCopy_32((BNWORD32 *)dest->ptr,
- (BNWORD32 *)src->ptr, s);
- }
-
- i = lbnInv_32((BNWORD32 *)dest->ptr, s, (BNWORD32 *)mod->ptr, m);
- if (i == 0)
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, m);
-
- MALLOCDB;
- return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_32(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
- BNWORD32 carry;
-
- if (amt % 32) {
- carry = lbnLshift_32((BNWORD32 *)dest->ptr, s, amt % 32);
- if (carry) {
- s++;
- bnSizeCheck(dest, s);
- ((BNWORD32 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
- }
- }
-
- amt /= 32;
- if (amt) {
- bnSizeCheck(dest, s+amt);
- memmove((BNWORD32 *)dest->ptr BIGLITTLE(-s-amt, +amt),
- (BNWORD32 *)dest->ptr BIG(-s),
- s * sizeof(BNWORD32));
- lbnZero_32((BNWORD32 *)dest->ptr, amt);
- s += amt;
- }
- dest->size = s;
- MALLOCDB;
- return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_32(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
-
- if (amt >= 32) {
- memmove(
- (BNWORD32 *)dest->ptr BIG(-s+amt/32),
- (BNWORD32 *)dest->ptr BIGLITTLE(-s, +amt/32),
- (s-amt/32) * sizeof(BNWORD32));
- s -= amt/32;
- amt %= 32;
- }
-
- if (amt)
- (void)lbnRshift_32((BNWORD32 *)dest->ptr, s, amt);
-
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s);
- MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted. n = d * 2^s. Replaces n with d and returns s.
- * Returns 0 when given 0. (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_32(struct BigNum *n)
-{
- unsigned size;
- unsigned s; /* shift amount */
- BNWORD32 *p;
- BNWORD32 t;
-
- p = (BNWORD32 *)n->ptr;
- size = lbnNorm_32(p, n->size);
- if (!size)
- return 0;
-
- t = BIGLITTLE(p[-1],p[0]);
- s = 0;
-
- /* See how many words we have to shift */
- if (!t) {
- /* Shift by words */
- do {
- s++;
- BIGLITTLE(--p,p++);
- } while ((t = BIGLITTLE(p[-1],p[0])) == 0);
- size -= s;
- s *= 32;
- memmove((BNWORD32 *)n->ptr BIG(-size), p BIG(-size),
- size * sizeof(BNWORD32));
- p = (BNWORD32 *)n->ptr;
- MALLOCDB;
- }
-
- assert(t);
-
- if (!(t & 1)) {
- /* Now count the bits */
- do {
- t >>= 1;
- s++;
- } while ((t & 1) == 0);
-
- /* Shift the bits */
- lbnRshift_32(p, size, s & (32-1));
- /* Renormalize */
- if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
- --size;
- }
- n->size = size;
-
- MALLOCDB;
- return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn32.c for the details on how the algorithm works. Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired. To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- *
- * This implementation allows only power-of-2 values for "order". Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 320 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- *
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order). (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At 2 bits, order 2 uses 0.000000 multiplies
- * At 4 bits, order 2 uses 1.000000 multiplies
- * At 8 bits, order 2 uses 3.000000 multiplies
- * At 1_6 bits, order 2 uses 7.000000 multiplies
- * At 3_2 bits, order 2 uses 15.000000 multiplies
- * At 34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At 6_4 bits, order 4 uses 27.000000 multiplies
- * At 99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At 128 bits, order 8 uses 48.500000 multiplies
- * At 256 bits, order 8 uses 85.875000 multiplies
- * At 280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At 512 bits, order 1_6 uses 147.000000 multiplies
- * At 785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At 1024 bits, order 3_2 uses 257.562500 multiplies
- * At 2048 bits, order 3_2 uses 456.093750 multiplies
- * At 2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At 4096 bits, order 6_4 uses 795.281250 multiplies
- * At 5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At 8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_32(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits)
-{
- int i;
- BNWORD32 **array; /* Array of precomputed powers of base */
- unsigned n; /* Number of entries in array (needed) */
- unsigned m; /* Number of entries in array (non-NULL) */
- unsigned arraysize; /* Number of entries in array (allocated) */
- unsigned bits; /* log2(order) */
- unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
- static unsigned const bnBasePrecompThreshTable[] = {
- 33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
- };
-
- /* Clear pre in case of failure */
- pre->array = 0;
- pre->msize = 0;
- pre->bits = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-
- /* Find the correct bit-window size */
- bits = 0;
- do
- bits++;
- while (maxebits > bnBasePrecompThreshTable[bits]);
-
- /* Now the number of precomputed values we need */
- n = (maxebits+bits-1)/bits;
- assert(n*bits >= maxebits);
-
- arraysize = n+1; /* Add one trailing NULL for safety */
- array = lbnMemAlloc(arraysize * sizeof(*array));
- if (!array)
- return -1; /* Out of memory */
-
- /* Now allocate the entries (precomputed powers of base) */
- for (m = 0; m < n; m++) {
- BNWORD32 *entry;
-
- LBNALLOC(entry, BNWORD32, msize);
- if (!entry)
- break;
- array[m] = entry;
- }
-
- /* "m" is the number of successfully allocated entries */
- if (m < n) {
- /* Ran out of memory; see if we can use a smaller array */
- BNWORD32 **newarray;
-
- if (m < 2) {
- n = 0; /* Forget it */
- } else {
- /* How few bits can we use with what's allocated? */
- bits = (maxebits + m - 1) / m;
-retry:
- n = (maxebits + bits - 1) / bits;
- if (! (n >> bits) )
- n = 0; /* Not enough to amount to anything */
- }
- /* Free excess allocated array entries */
- while (m > n) {
- BNWORD32 *entry = array[--m];
- LBNFREE(entry, msize);
- }
- if (!n) {
- /* Give it up */
- lbnMemFree(array, arraysize * sizeof(*array));
- return -1;
- }
- /*
- * Try to shrink the pointer array. This might fail, but
- * it's not critical. lbnMemRealloc isn't guarnateed to
- * exist, so we may have to allocate, copy, and free.
- */
-#ifdef lbnMemRealloc
- newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
- (n+1) * sizeof(*array));
- if (newarray) {
- array = newarray;
- arraysize = n+1;
- }
-#else
- newarray = lbnMemAlloc((n+1) * sizeof(*array));
- if (newarray) {
- memcpy(newarray, array, n * sizeof(*array));
- lbnMemFree(array, arraysize * sizeof(*array));
- array = newarray;
- arraysize = n+1;
- }
-#endif
- }
-
- /* Pad with null pointers */
- while (m < arraysize)
- array[m++] = 0;
-
- /* Okay, we have our array, now initialize it */
- i = lbnBasePrecompBegin_32(array, n, bits,
- (BNWORD32 *)base->ptr, base->size,
- (BNWORD32 *)mod->ptr, msize);
- if (i < 0) {
- /* Ack, still out of memory */
- bits++;
- m = n;
- goto retry;
- }
- /* Finally, totoal success */
- pre->array = array;
- pre->bits = bits;
- pre->msize = msize;
- pre->maxebits = n * bits;
- pre->arraysize = arraysize;
- pre->entries = n;
- return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_32(struct BnBasePrecomp *pre)
-{
- BNWORD32 **array = pre->array;
-
- if (array) {
- unsigned entries = pre->entries;
- unsigned msize = pre->msize;
- unsigned m;
-
- for (m = 0; m < entries; m++) {
- BNWORD32 *entry = array[m];
- if (entry)
- LBNFREE(entry, msize);
- }
- lbnMemFree(array, pre->arraysize * sizeof(array));
- }
- pre->array = 0;
- pre->bits = 0;
- pre->msize = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_32(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
- unsigned esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
- BNWORD32 const * const *array = pre->array;
- int i;
-
- assert(msize == pre->msize);
- assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_32((BNWORD32 *)exp->ptr, esize) <= pre->maxebits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnBasePrecompExp_32(dest->ptr, array, pre->bits,
- exp->ptr, esize, mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
- return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_32(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
- unsigned e1size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp1->size);
- unsigned e2size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp2->size);
- BNWORD32 const * const *array1 = pre1->array;
- BNWORD32 const * const *array2 = pre2->array;
- int i;
-
- assert(msize == pre1->msize);
- assert(msize == pre2->msize);
- assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_32((BNWORD32 *)exp1->ptr, e1size) <= pre1->maxebits);
- assert(lbnBits_32((BNWORD32 *)exp2->ptr, e2size) <= pre2->maxebits);
- assert(pre1->bits == pre2->bits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnDoubleBasePrecompExp_32(dest->ptr, pre1->bits, array1,
- exp1->ptr, e1size, array2, exp2->ptr, e2size,
- mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
- return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn32.h b/jni/libzrtp/sources/bnlib/bn32.h
deleted file mode 100644
index 7beba61..0000000
--- a/jni/libzrtp/sources/bnlib/bn32.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn32.h - interface to 32-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_32(void);
-void bnEnd_32(struct BigNum *bn);
-int bnPrealloc_32(struct BigNum *bn, unsigned bits);
-int bnCopy_32(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_32(struct BigNum *a, struct BigNum *b);
-void bnNorm_32(struct BigNum *bn);
-void bnExtractBigBytes_32(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_32(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_32(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_32(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-unsigned bnLSWord_32(struct BigNum const *src);
-int bnReadBit_32(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_32(struct BigNum const *src);
-int bnAdd_32(struct BigNum *dest, struct BigNum const *src);
-int bnSub_32(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_32(struct BigNum const *a, unsigned b);
-int bnSetQ_32(struct BigNum *dest, unsigned src);
-int bnAddQ_32(struct BigNum *dest, unsigned src);
-int bnSubQ_32(struct BigNum *dest, unsigned src);
-int bnCmp_32(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_32(struct BigNum *dest, struct BigNum const *src);
-int bnMul_32(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnMulQ_32(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_32(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d);
-int bnMod_32(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *d);
-unsigned bnModQ_32(struct BigNum const *src, unsigned d);
-int bnExpMod_32(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_32(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod);
-int bnTwoExpMod_32(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod);
-int bnGcd_32(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnInv_32(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod);
-int bnLShift_32(struct BigNum *dest, unsigned amt);
-void bnRShift_32(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_32(struct BigNum *n);
-int bnBasePrecompBegin_32(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_32(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_32(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_32(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn64.c b/jni/libzrtp/sources/bnlib/bn64.c
deleted file mode 100644
index 23cf185..0000000
--- a/jni/libzrtp/sources/bnlib/bn64.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn64.c - the high-level bignum interface
- *
- * Like lbn64.c, this reserves the string "64" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it. DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn64.h"
-#include "lbnmem.h"
-#include "bn64.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h" /* For memmove() */
-
-/* Functions */
-void
-bnInit_64(void)
-{
- bnEnd = bnEnd_64;
- bnPrealloc = bnPrealloc_64;
- bnCopy = bnCopy_64;
- bnNorm = bnNorm_64;
- bnExtractBigBytes = bnExtractBigBytes_64;
- bnInsertBigBytes = bnInsertBigBytes_64;
- bnExtractLittleBytes = bnExtractLittleBytes_64;
- bnInsertLittleBytes = bnInsertLittleBytes_64;
- bnLSWord = bnLSWord_64;
- bnReadBit = bnReadBit_64;
- bnBits = bnBits_64;
- bnAdd = bnAdd_64;
- bnSub = bnSub_64;
- bnCmpQ = bnCmpQ_64;
- bnSetQ = bnSetQ_64;
- bnAddQ = bnAddQ_64;
- bnSubQ = bnSubQ_64;
- bnCmp = bnCmp_64;
- bnSquare = bnSquare_64;
- bnMul = bnMul_64;
- bnMulQ = bnMulQ_64;
- bnDivMod = bnDivMod_64;
- bnMod = bnMod_64;
- bnModQ = bnModQ_64;
- bnExpMod = bnExpMod_64;
- bnDoubleExpMod = bnDoubleExpMod_64;
- bnTwoExpMod = bnTwoExpMod_64;
- bnGcd = bnGcd_64;
- bnInv = bnInv_64;
- bnLShift = bnLShift_64;
- bnRShift = bnRShift_64;
- bnMakeOdd = bnMakeOdd_64;
- bnBasePrecompBegin = bnBasePrecompBegin_64;
- bnBasePrecompEnd = bnBasePrecompEnd_64;
- bnBasePrecompExpMod = bnBasePrecompExpMod_64;
- bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_64;
-}
-
-void
-bnEnd_64(struct BigNum *bn)
-{
- if (bn->ptr) {
- LBNFREE((BNWORD64 *)bn->ptr, bn->allocated);
- bn->ptr = 0;
- }
- bn->size = 0;
- bn->allocated = 0;
-
- MALLOCDB;
-}
-
-/* Internal function. It operates in words. */
-static int
-bnResize_64(struct BigNum *bn, unsigned len)
-{
- void *p;
-
- /* Round size up: most mallocs impose 8-byte granularity anyway */
- len = (len + (8/sizeof(BNWORD64) - 1)) & ~(8/sizeof(BNWORD64) - 1);
- p = LBNREALLOC((BNWORD64 *)bn->ptr, bn->allocated, len);
- if (!p)
- return -1;
- bn->ptr = p;
- bn->allocated = len;
-
- MALLOCDB;
-
- return 0;
-}
-
-#define bnSizeCheck(bn, size) \
- if (bn->allocated < size && bnResize_64(bn, size) < 0) \
- return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_64(struct BigNum *bn, unsigned bits)
-{
- bits = (bits + 64-1)/64;
- bnSizeCheck(bn, bits);
- MALLOCDB;
- return 0;
-}
-
-int
-bnCopy_64(struct BigNum *dest, struct BigNum const *src)
-{
- bnSizeCheck(dest, src->size);
- dest->size = src->size;
- lbnCopy_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, src->size);
- MALLOCDB;
- return 0;
-}
-
-/* Is this ever needed? Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_64(struct BigNum *bn)
-{
- bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes. Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_64(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (64 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len) {
- *dest++ = 0;
- len--;
- }
-
- if (len)
- lbnExtractBigBytes_64((BNWORD64 *)bn->ptr, dest, lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_64(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD64)-1) / sizeof(BNWORD64);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_64((BNWORD64 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertBigBytes_64((BNWORD64 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes. Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_64(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size * (64 / 8);
-
- /* Fill unused leading bytes with 0 */
- while (s < lsbyte + len)
- dest[--len] = 0;
-
- if (len)
- lbnExtractLittleBytes_64((BNWORD64 *)bn->ptr, dest,
- lsbyte, len);
- MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_64(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len)
-{
- unsigned s = bn->size;
- unsigned words = (len+lsbyte+sizeof(BNWORD64)-1) / sizeof(BNWORD64);
-
- /* Pad with zeros as required */
- bnSizeCheck(bn, words);
-
- if (s < words) {
- lbnZero_64((BNWORD64 *)bn->ptr BIGLITTLE(-s,+s), words-s);
- s = words;
- }
-
- lbnInsertLittleBytes_64((BNWORD64 *)bn->ptr, src, lsbyte, len);
-
- bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, s);
-
- MALLOCDB;
- return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_64(struct BigNum const *bn)
-{
- return bn->size ? (unsigned)((BNWORD64 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_64(struct BigNum const *bn, unsigned bit)
-{
- BNWORD64 word;
- if (bit/64 >= bn->size)
- return 0;
- word = ((BNWORD64 *)bn->ptr)[BIGLITTLE(-1-bit/64,bit/64)];
- return (int)(word >> (bit % 64) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_64(struct BigNum const *bn)
-{
- return lbnBits_64((BNWORD64 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_64(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD64 t;
-
- if (!s)
- return 0;
-
- bnSizeCheck(dest, s);
-
- if (d < s) {
- lbnZero_64((BNWORD64 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- t = lbnAddN_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnAdd1_64((BNWORD64 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- bnSizeCheck(dest, d+1);
- ((BNWORD64 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
- dest->size = d+1;
- }
- }
- return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_64(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s = src->size, d = dest->size;
- BNWORD64 t;
-
- if (d < s && d < (s = lbnNorm_64((BNWORD64 *)src->ptr, s))) {
- bnSizeCheck(dest, s);
- lbnZero_64((BNWORD64 *)dest->ptr BIGLITTLE(-d,+d), s-d);
- dest->size = d = s;
- MALLOCDB;
- }
- if (!s)
- return 0;
- t = lbnSubN_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
- MALLOCDB;
- if (t) {
- if (d > s) {
- t = lbnSub1_64((BNWORD64 *)dest->ptr BIGLITTLE(-s,+s),
- d-s, t);
- MALLOCDB;
- }
- if (t) {
- lbnNeg_64((BNWORD64 *)dest->ptr, d);
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr,
- dest->size);
- MALLOCDB;
- return 1;
- }
- }
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dest->size);
- return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_64(struct BigNum const *a, unsigned b)
-{
- unsigned t;
- BNWORD64 v;
-
- t = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
- /* If a is more than one word long or zero, it's easy... */
- if (t != 1)
- return (t > 1) ? 1 : (b ? -1 : 0);
- v = (unsigned)((BNWORD64 *)a->ptr)[BIGLITTLE(-1,0)];
- return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_64(struct BigNum *dest, unsigned src)
-{
- if (src) {
- bnSizeCheck(dest, 1);
-
- ((BNWORD64 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD64)src;
- dest->size = 1;
- } else {
- dest->size = 0;
- }
- return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_64(struct BigNum *dest, unsigned src)
-{
- BNWORD64 t;
-
- if (!dest->size)
- return bnSetQ(dest, src);
-
- t = lbnAdd1_64((BNWORD64 *)dest->ptr, dest->size, (BNWORD64)src);
- MALLOCDB;
- if (t) {
- src = dest->size;
- bnSizeCheck(dest, src+1);
- ((BNWORD64 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
- dest->size = src+1;
- }
- return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_64(struct BigNum *dest, unsigned src)
-{
- BNWORD64 t;
-
- if (!dest->size)
- return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
- t = lbnSub1_64((BNWORD64 *)dest->ptr, dest->size, src);
- MALLOCDB;
- if (t) {
- /* Underflow. <= 1 word, so do it simply. */
- lbnNeg_64((BNWORD64 *)dest->ptr, 1);
- dest->size = 1;
- return 1;
- }
-/* Try to normalize? Needing this is going to be pretty damn rare. */
-/* dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dest->size); */
- return 0;
-}
-
-/*
- * Compare two BigNums. Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_64(struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
-
- s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
- t = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
- if (s != t)
- return s > t ? 1 : -1;
- return lbnCmp_64((BNWORD64 *)a->ptr, (BNWORD64 *)b->ptr, s);
-}
-
-/* dest = src*src. This is more efficient than bnMul. */
-int
-bnSquare_64(struct BigNum *dest, struct BigNum const *src)
-{
- unsigned s;
- BNWORD64 *srcbuf;
-
- s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
- if (!s) {
- dest->size = 0;
- return 0;
- }
- bnSizeCheck(dest, 2*s);
-
- if (src == dest) {
- LBNALLOC(srcbuf, BNWORD64, s);
- if (!srcbuf)
- return -1;
- lbnCopy_64(srcbuf, (BNWORD64 *)src->ptr, s);
- lbnSquare_64((BNWORD64 *)dest->ptr, (BNWORD64 *)srcbuf, s);
- LBNFREE(srcbuf, s);
- } else {
- lbnSquare_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
- }
-
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, 2*s);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b. Any overlap between operands is allowed. */
-int
-bnMul_64(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- unsigned s, t;
- BNWORD64 *srcbuf;
-
- s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
- t = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
- if (!s || !t) {
- dest->size = 0;
- return 0;
- }
-
- if (a == b)
- return bnSquare_64(dest, a);
-
- bnSizeCheck(dest, s+t);
-
- if (dest == a) {
- LBNALLOC(srcbuf, BNWORD64, s);
- if (!srcbuf)
- return -1;
- lbnCopy_64(srcbuf, (BNWORD64 *)a->ptr, s);
- lbnMul_64((BNWORD64 *)dest->ptr, srcbuf, s,
- (BNWORD64 *)b->ptr, t);
- LBNFREE(srcbuf, s);
- } else if (dest == b) {
- LBNALLOC(srcbuf, BNWORD64, t);
- if (!srcbuf)
- return -1;
- lbnCopy_64(srcbuf, (BNWORD64 *)b->ptr, t);
- lbnMul_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s,
- srcbuf, t);
- LBNFREE(srcbuf, t);
- } else {
- lbnMul_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s,
- (BNWORD64 *)b->ptr, t);
- }
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s+t);
- MALLOCDB;
- return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_64(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
- unsigned s;
-
- s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
- if (!s || !b) {
- dest->size = 0;
- return 0;
- }
- if (b == 1)
- return bnCopy_64(dest, a);
- bnSizeCheck(dest, s+1);
- lbnMulN1_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s, b);
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s+1);
- MALLOCDB;
- return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_64(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d)
-{
- unsigned dsize, nsize;
- BNWORD64 qhigh;
-
- dsize = lbnNorm_64((BNWORD64 *)d->ptr, d->size);
- nsize = lbnNorm_64((BNWORD64 *)n->ptr, n->size);
-
- if (nsize < dsize) {
- q->size = 0; /* No quotient */
- r->size = nsize;
- return 0; /* Success */
- }
-
- bnSizeCheck(q, nsize-dsize);
-
- if (r != n) { /* You are allowed to reduce in place */
- bnSizeCheck(r, nsize);
- lbnCopy_64((BNWORD64 *)r->ptr, (BNWORD64 *)n->ptr, nsize);
- }
-
- qhigh = lbnDiv_64((BNWORD64 *)q->ptr, (BNWORD64 *)r->ptr, nsize,
- (BNWORD64 *)d->ptr, dsize);
- nsize -= dsize;
- if (qhigh) {
- bnSizeCheck(q, nsize+1);
- *((BNWORD64 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
- q->size = nsize+1;
- } else {
- q->size = lbnNorm_64((BNWORD64 *)q->ptr, nsize);
- }
- r->size = lbnNorm_64((BNWORD64 *)r->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* det = src % d */
-int
-bnMod_64(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
- unsigned dsize, nsize;
-
- nsize = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
- dsize = lbnNorm_64((BNWORD64 *)d->ptr, d->size);
-
-
- if (dest != src) {
- bnSizeCheck(dest, nsize);
- lbnCopy_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, nsize);
- }
-
- if (nsize < dsize) {
- dest->size = nsize; /* No quotient */
- return 0;
- }
-
- (void)lbnDiv_64((BNWORD64 *)dest->ptr BIGLITTLE(-dsize,+dsize),
- (BNWORD64 *)dest->ptr, nsize,
- (BNWORD64 *)d->ptr, dsize);
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dsize);
- MALLOCDB;
- return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_64(struct BigNum const *src, unsigned d)
-{
- unsigned s;
-
- s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
- if (!s)
- return 0;
-
- if (d & (d-1)) /* Not a power of 2 */
- d = lbnModQ_64((BNWORD64 *)src->ptr, s, d);
- else
- d = (unsigned)((BNWORD64 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
- return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_64(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned nsize, esize, msize;
-
- nsize = lbnNorm_64((BNWORD64 *)n->ptr, n->size);
- esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
- msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- /* Special-case base of 2 */
- if (nsize == 1 && ((BNWORD64 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
- if (lbnTwoExpMod_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)exp->ptr, esize,
- (BNWORD64 *)mod->ptr, msize) < 0)
- return -1;
- } else {
- if (lbnExpMod_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)n->ptr, nsize,
- (BNWORD64 *)exp->ptr, esize,
- (BNWORD64 *)mod->ptr, msize) < 0)
- return -1;
- }
-
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod). This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_64(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod)
-{
- unsigned n1size, e1size, n2size, e2size, msize;
-
- n1size = lbnNorm_64((BNWORD64 *)n1->ptr, n1->size);
- e1size = lbnNorm_64((BNWORD64 *)e1->ptr, e1->size);
- n2size = lbnNorm_64((BNWORD64 *)n2->ptr, n2->size);
- e2size = lbnNorm_64((BNWORD64 *)e2->ptr, e2->size);
- msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(dest, msize);
-
- if (lbnDoubleExpMod_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)n1->ptr, n1size, (BNWORD64 *)e1->ptr, e1size,
- (BNWORD64 *)n2->ptr, n2size, (BNWORD64 *)e2->ptr, e2size,
- (BNWORD64 *)mod->ptr, msize) < 0)
- return -1;
-
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_64(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod)
-{
- unsigned esize, msize;
-
- esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
- msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
- if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
- return -1; /* Illegal modulus! */
-
- bnSizeCheck(n, msize);
-
- if (lbnTwoExpMod_64((BNWORD64 *)n->ptr, (BNWORD64 *)exp->ptr, esize,
- (BNWORD64 *)mod->ptr, msize) < 0)
- return -1;
-
- n->size = lbnNorm_64((BNWORD64 *)n->ptr, msize);
- MALLOCDB;
- return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_64(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
- BNWORD64 *tmp;
- unsigned asize, bsize;
- int i;
-
- /* Kind of silly, but we might as well permit it... */
- if (a == b)
- return dest == a ? 0 : bnCopy(dest, a);
-
- /* Ensure a is not the same as "dest" */
- if (a == dest) {
- a = b;
- b = dest;
- }
-
- asize = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
- bsize = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
- bnSizeCheck(dest, bsize+1);
-
- /* Copy a to tmp */
- LBNALLOC(tmp, BNWORD64, asize+1);
- if (!tmp)
- return -1;
- lbnCopy_64(tmp, (BNWORD64 *)a->ptr, asize);
-
- /* Copy b to dest, if necessary */
- if (dest != b)
- lbnCopy_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)b->ptr, bsize);
- if (bsize > asize || (bsize == asize &&
- lbnCmp_64((BNWORD64 *)b->ptr, (BNWORD64 *)a->ptr, asize) > 0))
- {
- i = lbnGcd_64((BNWORD64 *)dest->ptr, bsize, tmp, asize,
- &dest->size);
- if (i > 0) /* Result in tmp, not dest */
- lbnCopy_64((BNWORD64 *)dest->ptr, tmp, dest->size);
- } else {
- i = lbnGcd_64(tmp, asize, (BNWORD64 *)dest->ptr, bsize,
- &dest->size);
- if (i == 0) /* Result in tmp, not dest */
- lbnCopy_64((BNWORD64 *)dest->ptr, tmp, dest->size);
- }
- LBNFREE(tmp, asize+1);
- MALLOCDB;
- return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod). Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_64(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod)
-{
- unsigned s, m;
- int i;
-
- s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
- m = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
- /* lbnInv_64 requires that the input be less than the modulus */
- if (m < s ||
- (m==s && lbnCmp_64((BNWORD64 *)src->ptr, (BNWORD64 *)mod->ptr, s)))
- {
- bnSizeCheck(dest, s + (m==s));
- if (dest != src)
- lbnCopy_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)src->ptr, s);
- /* Pre-reduce modulo the modulus */
- (void)lbnDiv_64((BNWORD64 *)dest->ptr BIGLITTLE(-m,+m),
- (BNWORD64 *)dest->ptr, s,
- (BNWORD64 *)mod->ptr, m);
- s = lbnNorm_64((BNWORD64 *)dest->ptr, m);
- MALLOCDB;
- } else {
- bnSizeCheck(dest, m+1);
- if (dest != src)
- lbnCopy_64((BNWORD64 *)dest->ptr,
- (BNWORD64 *)src->ptr, s);
- }
-
- i = lbnInv_64((BNWORD64 *)dest->ptr, s, (BNWORD64 *)mod->ptr, m);
- if (i == 0)
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, m);
-
- MALLOCDB;
- return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_64(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
- BNWORD64 carry;
-
- if (amt % 64) {
- carry = lbnLshift_64((BNWORD64 *)dest->ptr, s, amt % 64);
- if (carry) {
- s++;
- bnSizeCheck(dest, s);
- ((BNWORD64 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
- }
- }
-
- amt /= 64;
- if (amt) {
- bnSizeCheck(dest, s+amt);
- memmove((BNWORD64 *)dest->ptr BIGLITTLE(-s-amt, +amt),
- (BNWORD64 *)dest->ptr BIG(-s),
- s * sizeof(BNWORD64));
- lbnZero_64((BNWORD64 *)dest->ptr, amt);
- s += amt;
- }
- dest->size = s;
- MALLOCDB;
- return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_64(struct BigNum *dest, unsigned amt)
-{
- unsigned s = dest->size;
-
- if (amt >= 64) {
- memmove(
- (BNWORD64 *)dest->ptr BIG(-s+amt/64),
- (BNWORD64 *)dest->ptr BIGLITTLE(-s, +amt/64),
- (s-amt/64) * sizeof(BNWORD64));
- s -= amt/64;
- amt %= 64;
- }
-
- if (amt)
- (void)lbnRshift_64((BNWORD64 *)dest->ptr, s, amt);
-
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s);
- MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted. n = d * 2^s. Replaces n with d and returns s.
- * Returns 0 when given 0. (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_64(struct BigNum *n)
-{
- unsigned size;
- unsigned s; /* shift amount */
- BNWORD64 *p;
- BNWORD64 t;
-
- p = (BNWORD64 *)n->ptr;
- size = lbnNorm_64(p, n->size);
- if (!size)
- return 0;
-
- t = BIGLITTLE(p[-1],p[0]);
- s = 0;
-
- /* See how many words we have to shift */
- if (!t) {
- /* Shift by words */
- do {
- s++;
- BIGLITTLE(--p,p++);
- } while ((t = BIGLITTLE(p[-1],p[0])) == 0);
- size -= s;
- s *= 64;
- memmove((BNWORD64 *)n->ptr BIG(-size), p BIG(-size),
- size * sizeof(BNWORD64));
- p = (BNWORD64 *)n->ptr;
- MALLOCDB;
- }
-
- assert(t);
-
- if (!(t & 1)) {
- /* Now count the bits */
- do {
- t >>= 1;
- s++;
- } while ((t & 1) == 0);
-
- /* Shift the bits */
- lbnRshift_64(p, size, s & (64-1));
- /* Renormalize */
- if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
- --size;
- }
- n->size = size;
-
- MALLOCDB;
- return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn64.c for the details on how the algorithm works. Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired. To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- *
- * This implementation allows only power-of-2 values for "order". Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 640 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- *
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order). (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At 2 bits, order 2 uses 0.000000 multiplies
- * At 4 bits, order 2 uses 1.000000 multiplies
- * At 8 bits, order 2 uses 3.000000 multiplies
- * At 1_6 bits, order 2 uses 7.000000 multiplies
- * At 3_2 bits, order 2 uses 15.000000 multiplies
- * At 34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At 6_4 bits, order 4 uses 27.000000 multiplies
- * At 99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At 128 bits, order 8 uses 48.500000 multiplies
- * At 256 bits, order 8 uses 85.875000 multiplies
- * At 280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At 512 bits, order 1_6 uses 147.000000 multiplies
- * At 785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At 1024 bits, order 3_2 uses 257.562500 multiplies
- * At 2048 bits, order 3_2 uses 456.093750 multiplies
- * At 2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At 4096 bits, order 6_4 uses 795.281250 multiplies
- * At 5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At 8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_64(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits)
-{
- int i;
- BNWORD64 **array; /* Array of precomputed powers of base */
- unsigned n; /* Number of entries in array (needed) */
- unsigned m; /* Number of entries in array (non-NULL) */
- unsigned arraysize; /* Number of entries in array (allocated) */
- unsigned bits; /* log2(order) */
- unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
- static unsigned const bnBasePrecompThreshTable[] = {
- 33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
- };
-
- /* Clear pre in case of failure */
- pre->array = 0;
- pre->msize = 0;
- pre->bits = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-
- /* Find the correct bit-window size */
- bits = 0;
- do
- bits++;
- while (maxebits > bnBasePrecompThreshTable[bits]);
-
- /* Now the number of precomputed values we need */
- n = (maxebits+bits-1)/bits;
- assert(n*bits >= maxebits);
-
- arraysize = n+1; /* Add one trailing NULL for safety */
- array = lbnMemAlloc(arraysize * sizeof(*array));
- if (!array)
- return -1; /* Out of memory */
-
- /* Now allocate the entries (precomputed powers of base) */
- for (m = 0; m < n; m++) {
- BNWORD64 *entry;
-
- LBNALLOC(entry, BNWORD64, msize);
- if (!entry)
- break;
- array[m] = entry;
- }
-
- /* "m" is the number of successfully allocated entries */
- if (m < n) {
- /* Ran out of memory; see if we can use a smaller array */
- BNWORD64 **newarray;
-
- if (m < 2) {
- n = 0; /* Forget it */
- } else {
- /* How few bits can we use with what's allocated? */
- bits = (maxebits + m - 1) / m;
-retry:
- n = (maxebits + bits - 1) / bits;
- if (! (n >> bits) )
- n = 0; /* Not enough to amount to anything */
- }
- /* Free excess allocated array entries */
- while (m > n) {
- BNWORD64 *entry = array[--m];
- LBNFREE(entry, msize);
- }
- if (!n) {
- /* Give it up */
- lbnMemFree(array, arraysize * sizeof(*array));
- return -1;
- }
- /*
- * Try to shrink the pointer array. This might fail, but
- * it's not critical. lbnMemRealloc isn't guarnateed to
- * exist, so we may have to allocate, copy, and free.
- */
-#ifdef lbnMemRealloc
- newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
- (n+1) * sizeof(*array));
- if (newarray) {
- array = newarray;
- arraysize = n+1;
- }
-#else
- newarray = lbnMemAlloc((n+1) * sizeof(*array));
- if (newarray) {
- memcpy(newarray, array, n * sizeof(*array));
- lbnMemFree(array, arraysize * sizeof(*array));
- array = newarray;
- arraysize = n+1;
- }
-#endif
- }
-
- /* Pad with null pointers */
- while (m < arraysize)
- array[m++] = 0;
-
- /* Okay, we have our array, now initialize it */
- i = lbnBasePrecompBegin_64(array, n, bits,
- (BNWORD64 *)base->ptr, base->size,
- (BNWORD64 *)mod->ptr, msize);
- if (i < 0) {
- /* Ack, still out of memory */
- bits++;
- m = n;
- goto retry;
- }
- /* Finally, totoal success */
- pre->array = array;
- pre->bits = bits;
- pre->msize = msize;
- pre->maxebits = n * bits;
- pre->arraysize = arraysize;
- pre->entries = n;
- return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_64(struct BnBasePrecomp *pre)
-{
- BNWORD64 **array = pre->array;
-
- if (array) {
- unsigned entries = pre->entries;
- unsigned msize = pre->msize;
- unsigned m;
-
- for (m = 0; m < entries; m++) {
- BNWORD64 *entry = array[m];
- if (entry)
- LBNFREE(entry, msize);
- }
- lbnMemFree(array, pre->arraysize * sizeof(array));
- }
- pre->array = 0;
- pre->bits = 0;
- pre->msize = 0;
- pre->maxebits = 0;
- pre->arraysize = 0;
- pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_64(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
- unsigned esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
- BNWORD64 const * const *array = pre->array;
- int i;
-
- assert(msize == pre->msize);
- assert(((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_64((BNWORD64 *)exp->ptr, esize) <= pre->maxebits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnBasePrecompExp_64(dest->ptr, array, pre->bits,
- exp->ptr, esize, mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
- return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_64(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod)
-{
- unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
- unsigned e1size = lbnNorm_64((BNWORD64 *)exp1->ptr, exp1->size);
- unsigned e2size = lbnNorm_64((BNWORD64 *)exp1->ptr, exp2->size);
- BNWORD64 const * const *array1 = pre1->array;
- BNWORD64 const * const *array2 = pre2->array;
- int i;
-
- assert(msize == pre1->msize);
- assert(msize == pre2->msize);
- assert(((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
- assert(lbnBits_64((BNWORD64 *)exp1->ptr, e1size) <= pre1->maxebits);
- assert(lbnBits_64((BNWORD64 *)exp2->ptr, e2size) <= pre2->maxebits);
- assert(pre1->bits == pre2->bits);
-
- bnSizeCheck(dest, msize);
-
- i = lbnDoubleBasePrecompExp_64(dest->ptr, pre1->bits, array1,
- exp1->ptr, e1size, array2, exp2->ptr, e2size,
- mod->ptr, msize);
- if (i == 0)
- dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
- return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn64.h b/jni/libzrtp/sources/bnlib/bn64.h
deleted file mode 100644
index 1c23721..0000000
--- a/jni/libzrtp/sources/bnlib/bn64.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn64.h - interface to 64-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_64(void);
-void bnEnd_64(struct BigNum *bn);
-int bnPrealloc_64(struct BigNum *bn, unsigned bits);
-int bnCopy_64(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_64(struct BigNum *a, struct BigNum *b);
-void bnNorm_64(struct BigNum *bn);
-void bnExtractBigBytes_64(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_64(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_64(struct BigNum const *bn, unsigned char *dest,
- unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_64(struct BigNum *bn, unsigned char const *src,
- unsigned lsbyte, unsigned len);
-unsigned bnLSWord_64(struct BigNum const *src);
-int bnReadBit_64(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_64(struct BigNum const *src);
-int bnAdd_64(struct BigNum *dest, struct BigNum const *src);
-int bnSub_64(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_64(struct BigNum const *a, unsigned b);
-int bnSetQ_64(struct BigNum *dest, unsigned src);
-int bnAddQ_64(struct BigNum *dest, unsigned src);
-int bnSubQ_64(struct BigNum *dest, unsigned src);
-int bnCmp_64(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_64(struct BigNum *dest, struct BigNum const *src);
-int bnMul_64(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnMulQ_64(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_64(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
- struct BigNum const *d);
-int bnMod_64(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *d);
-unsigned bnModQ_64(struct BigNum const *src, unsigned d);
-int bnExpMod_64(struct BigNum *dest, struct BigNum const *n,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_64(struct BigNum *dest,
- struct BigNum const *n1, struct BigNum const *e1,
- struct BigNum const *n2, struct BigNum const *e2,
- struct BigNum const *mod);
-int bnTwoExpMod_64(struct BigNum *n, struct BigNum const *exp,
- struct BigNum const *mod);
-int bnGcd_64(struct BigNum *dest, struct BigNum const *a,
- struct BigNum const *b);
-int bnInv_64(struct BigNum *dest, struct BigNum const *src,
- struct BigNum const *mod);
-int bnLShift_64(struct BigNum *dest, unsigned amt);
-void bnRShift_64(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_64(struct BigNum *n);
-int bnBasePrecompBegin_64(struct BnBasePrecomp *pre, struct BigNum const *base,
- struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_64(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_64(struct BigNum *dest, struct BnBasePrecomp const *pre,
- struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_64(struct BigNum *dest,
- struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
- struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
- struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bnconfig.h.cmake b/jni/libzrtp/sources/bnlib/bnconfig.h.cmake
deleted file mode 100644
index 2571de1..0000000
--- a/jni/libzrtp/sources/bnlib/bnconfig.h.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * bnconfig.h.cmake -- Configuration file for BigNum library.
- *
- * cmake processes this file.
- */
-#ifndef _BNCONFIG_H
-#define _BNCONFIG_H
-
-/* Checks for the presence and absence of various header files */
-#cmakedefine HAVE_ASSERT_H 1
-#define NO_ASSERT_H !HAVE_ASSERT_H
-
-#cmakedefine HAVE_LIMITS_H 1
-#define NO_LIMITS_H !HAVE_LIMITS_H
-
-#cmakedefine HAVE_STDLIB_H 1
-#define NO_STDLIB_H !HAVE_STDLIB_H
-
-#cmakedefine HAVE_STRING_H 1
-#define NO_STRING_H !HAVE_STRING_H
-
-#cmakedefine HAVE_STRINGS_H 1
-
-#cmakedefine NEED_MEMORY_H 1
-
-/* We go to some trouble to find accurate times... */
-
-/* Define if you have Posix.4 glock_gettime() */
-#cmakedefine HAVE_CLOCK_GETTIME 1
-/* Define if you have Solaris-style gethrvtime() */
-#cmakedefine HAVE_GETHRVTIME 1
-/* Define if you have getrusage() */
-#cmakedefine HAVE_GETRUSAGE 1
-/* Define if you have clock() */
-#cmakedefine HAVE_CLOCK 1
-/* Define if you have time() */
-#cmakedefine HAVE_TIME 1
-
-/*
- * Define as 0 if #including <sys/time.h> automatically
- * #includes <time.h>, and doing so explicitly causes an
- * error.
- */
-#define TIME_WITH_SYS_TIME 0
-
-/* Defines for various kinds of library brokenness */
-
-/* Define if <stdio.h> is missing prototypes (= lots of warnings!) */
-#cmakedefine NO_STDIO_PROTOS 1
-
-/* Define if <assert.h> depends on <stdio.h> and breaks without it */
-#cmakedefine ASSERT_NEEDS_STDIO 1
-/* Define if <assert.h> depends on <stdlib.h> and complains without it */
-#cmakedefine ASSERT_NEEDS_STDLIB 1
-
-/*
- * Define if <string.h> delcares the mem* functions to take char *
- * instead of void * parameters (= lots of warnings)
- */
-#cmakedefine MEM_PROTOS_BROKEN 1
-
-/* If not available, bcopy() is substituted */
-#cmakedefine HAVE_MEMMOVE 1
-#define NO_MEMMOVE !HAVE_MEMMOVE
-#cmakedefine HAVE_MEMCPY 1
-#define NO_MEMCPY !HAVE_MEMCPY
-
-#endif /* _BNCONFIG_H */
diff --git a/jni/libzrtp/sources/bnlib/bninit16.c b/jni/libzrtp/sources/bnlib/bninit16.c
deleted file mode 100644
index 16c6f3e..0000000
--- a/jni/libzrtp/sources/bnlib/bninit16.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit16.c - Provide an init function that sets things up for 16-bit
- * operation. This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn16.h"
-
-void
-bnInit(void)
-{
- bnInit_16();
-}
diff --git a/jni/libzrtp/sources/bnlib/bninit32.c b/jni/libzrtp/sources/bnlib/bninit32.c
deleted file mode 100644
index b27d363..0000000
--- a/jni/libzrtp/sources/bnlib/bninit32.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit32.c - Provide an init function that sets things up for 32-bit
- * operation. This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn32.h"
-
-void
-bnInit(void)
-{
- bnInit_32();
-}
diff --git a/jni/libzrtp/sources/bnlib/bninit64.c b/jni/libzrtp/sources/bnlib/bninit64.c
deleted file mode 100644
index 4abe673..0000000
--- a/jni/libzrtp/sources/bnlib/bninit64.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit64.c - Provide an init function that sets things up for 64-bit
- * operation. This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn64.h"
-
-void
-bnInit(void)
-{
- bnInit_64();
-}
diff --git a/jni/libzrtp/sources/bnlib/bnprint.c b/jni/libzrtp/sources/bnlib/bnprint.c
deleted file mode 100644
index a407248..0000000
--- a/jni/libzrtp/sources/bnlib/bnprint.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * bnprint.c - Print a bignum, for debugging purposes.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include "bnconfig.h"
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-
-#include <stdio.h>
-#include <stdint.h>
-
-#if !NO_STRING_H
-#include <string.h>
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include "bn.h"
-#include "bnprint.h"
-
-#include "kludge.h"
-
-int
-bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
- char const *suffix)
-{
- unsigned char temp[32]; /* How much to print on one line */
- unsigned len;
- size_t i;
-
- if (prefix && fputs(prefix, f) < 0)
- return EOF;
-
- len = (bnBits(bn) + 7)/ 8;
-
- if (!len) {
- if (putc('0', f) < 0)
- return EOF;
- } else {
- while (len > sizeof(temp)) {
- len -= sizeof(temp);
- bnExtractBigBytes(bn, temp, len, sizeof(temp));
- for (i = 0; i < sizeof(temp); i++)
- if (fprintf(f, "%02X", temp[i]) < 0)
- return EOF;
- if (putc('\\', f) < 0 || putc('\n', f) < 0)
- return EOF;
- if (prefix) {
- i = strlen(prefix);
- while (i--)
- if (putc(' ', f) < 0)
- return EOF;
- }
- }
- bnExtractBigBytes(bn, temp, 0, len);
- for (i = 0; i < len; i++)
- if (fprintf(f, "%02X", temp[i]) < 0)
- return EOF;
- }
- return suffix ? fputs(suffix, f) : 0;
-}
-
-/*
- * Convert an ASCII character to digit value
- */
-static int getAsciiDigit( uint32_t *d, int radix, char c )
-{
- *d = 255;
-
- if( c >= 0x30 && c <= 0x39 )
- *d = c - 0x30;
- if( c >= 0x41 && c <= 0x46 )
- *d = c - 0x37;
- if( c >= 0x61 && c <= 0x66 )
- *d = c - 0x57;
-
- if( *d >= (uint32_t)radix )
- return( -1 );
-
- return( 0 );
-}
-
-int
-bnReadAscii(struct BigNum *X, char *s, int radix)
-{
- int slen = strlen(s);
- int i, neg = 0;
- uint32_t d;
-
- bnSetQ(X, 0);
- for( i = 0; i < slen; i++ ) {
- if(i == 0 && s[i] == '-') {
- neg = 1;
- continue;
- }
- getAsciiDigit(&d, radix, s[i]);
- bnMulQ(X, X, radix);
-
- bnAddQ(X, d);
- }
- return(neg);
-}
diff --git a/jni/libzrtp/sources/bnlib/bnprint.h b/jni/libzrtp/sources/bnlib/bnprint.h
deleted file mode 100644
index b10393a..0000000
--- a/jni/libzrtp/sources/bnlib/bnprint.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef BNPRINT_H
-#define BNPRINT_H
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-struct BigNum;
-
-#ifndef SWIG
-int bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
- char const *suffix);
-#endif
-
-/**
- * Convert an ASCII string into a BigNum.
- *
- * This function converts an ASCII string into a Big number. If the first
- * character of the string is a minus sign the big number is a negative number.
- *
- * @param X the BigNum that stores the result
- *
- * @param s the ASCII string in big-endian format (first digit is most significant)
- *
- * @param radix the function can use radix between 2 and 16
- */
-int bnReadAscii(struct BigNum *X, char *s, int radix);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BNPRINT_H */
diff --git a/jni/libzrtp/sources/bnlib/bnsize00.h b/jni/libzrtp/sources/bnlib/bnsize00.h
deleted file mode 100644
index 962f486..0000000
--- a/jni/libzrtp/sources/bnlib/bnsize00.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * bnsize00.h - pick the correct machine word size to use.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#include "lbn.h" /* Get basic information */
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD64)
-# if defined(BNWORD128) || (defined(lbnMulAdd1_64) && defined(lbnMulSub1_64))
-# define BNSIZE64 1
-# elif defined(mul64_ppmm) || defined(mul64_ppmma) || defined(mul64_ppmmaa)
-# define BNSIZE64 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD32)
-# if defined(BNWORD64) || (defined(lbnMulAdd1_32) && defined(lbnMulSub1_32))
-# define BNSIZE32 1
-# elif defined(mul32_ppmm) || defined(mul32_ppmma) || defined(mul32_ppmmaa)
-# define BNSIZE32 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD16)
-# if defined(BNWORD32) || (defined(lbnMulAdd1_16) && defined(lbnMulSub1_16))
-# define BNSIZE16 1
-# elif defined(mul16_ppmm) || defined(mul16_ppmma) || defined(mul16_ppmmaa)
-# define BNSIZE16 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16
-#error Unable to find a viable word size to compile bignum library.
-#endif
diff --git a/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c b/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
deleted file mode 100644
index de11280..0000000
--- a/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/* Copyright 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * curve25519-donna: Curve25519 elliptic curve, public key function
- *
- * http://code.google.com/p/curve25519-donna/
- *
- * Adam Langley <agl@imperialviolet.org>
- *
- * Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
- *
- * More information about curve25519 can be found here
- * http://cr.yp.to/ecdh.html
- *
- * djb's sample implementation of curve25519 is written in a special assembly
- * language called qhasm and uses the floating point registers.
- *
- * This is, almost, a clean room reimplementation from the curve25519 paper. It
- * uses many of the tricks described therein. Only the crecip function is taken
- * from the sample implementation.
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#ifdef _MSC_VER
-#define inline __inline
-#endif
-
-typedef uint8_t u8;
-typedef int32_t s32;
-typedef int64_t limb;
-
-/* Field element representation:
- *
- * Field elements are written as an array of signed, 64-bit limbs, least
- * significant first. The value of the field element is:
- * x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
- *
- * i.e. the limbs are 26, 25, 26, 25, ... bits wide.
- */
-
-/* Sum two numbers: output += in */
-static void fsum(limb *output, const limb *in) {
- unsigned i;
- for (i = 0; i < 10; i += 2) {
- output[0+i] = (output[0+i] + in[0+i]);
- output[1+i] = (output[1+i] + in[1+i]);
- }
-}
-
-/* Find the difference of two numbers: output = in - output
- * (note the order of the arguments!)
- */
-static void fdifference(limb *output, const limb *in) {
- unsigned i;
- for (i = 0; i < 10; ++i) {
- output[i] = (in[i] - output[i]);
- }
-}
-
-/* Multiply a number by a scalar: output = in * scalar */
-static void fscalar_product(limb *output, const limb *in, const limb scalar) {
- unsigned i;
- for (i = 0; i < 10; ++i) {
- output[i] = in[i] * scalar;
- }
-}
-
-/* Multiply two numbers: output = in2 * in
- *
- * output must be distinct to both inputs. The inputs are reduced coefficient
- * form, the output is not.
- */
-static void fproduct(limb *output, const limb *in2, const limb *in) {
- output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
- output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
- ((limb) ((s32) in2[1])) * ((s32) in[0]);
- output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) +
- ((limb) ((s32) in2[0])) * ((s32) in[2]) +
- ((limb) ((s32) in2[2])) * ((s32) in[0]);
- output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) +
- ((limb) ((s32) in2[2])) * ((s32) in[1]) +
- ((limb) ((s32) in2[0])) * ((s32) in[3]) +
- ((limb) ((s32) in2[3])) * ((s32) in[0]);
- output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) +
- 2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
- ((limb) ((s32) in2[3])) * ((s32) in[1])) +
- ((limb) ((s32) in2[0])) * ((s32) in[4]) +
- ((limb) ((s32) in2[4])) * ((s32) in[0]);
- output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) +
- ((limb) ((s32) in2[3])) * ((s32) in[2]) +
- ((limb) ((s32) in2[1])) * ((s32) in[4]) +
- ((limb) ((s32) in2[4])) * ((s32) in[1]) +
- ((limb) ((s32) in2[0])) * ((s32) in[5]) +
- ((limb) ((s32) in2[5])) * ((s32) in[0]);
- output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
- ((limb) ((s32) in2[1])) * ((s32) in[5]) +
- ((limb) ((s32) in2[5])) * ((s32) in[1])) +
- ((limb) ((s32) in2[2])) * ((s32) in[4]) +
- ((limb) ((s32) in2[4])) * ((s32) in[2]) +
- ((limb) ((s32) in2[0])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[0]);
- output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) +
- ((limb) ((s32) in2[4])) * ((s32) in[3]) +
- ((limb) ((s32) in2[2])) * ((s32) in[5]) +
- ((limb) ((s32) in2[5])) * ((s32) in[2]) +
- ((limb) ((s32) in2[1])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[1]) +
- ((limb) ((s32) in2[0])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[0]);
- output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) +
- 2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
- ((limb) ((s32) in2[5])) * ((s32) in[3]) +
- ((limb) ((s32) in2[1])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[1])) +
- ((limb) ((s32) in2[2])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[2]) +
- ((limb) ((s32) in2[0])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[0]);
- output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) +
- ((limb) ((s32) in2[5])) * ((s32) in[4]) +
- ((limb) ((s32) in2[3])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[3]) +
- ((limb) ((s32) in2[2])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[2]) +
- ((limb) ((s32) in2[1])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[1]) +
- ((limb) ((s32) in2[0])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[0]);
- output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
- ((limb) ((s32) in2[3])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[3]) +
- ((limb) ((s32) in2[1])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[1])) +
- ((limb) ((s32) in2[4])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[4]) +
- ((limb) ((s32) in2[2])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[2]);
- output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) +
- ((limb) ((s32) in2[6])) * ((s32) in[5]) +
- ((limb) ((s32) in2[4])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[4]) +
- ((limb) ((s32) in2[3])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[3]) +
- ((limb) ((s32) in2[2])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[2]);
- output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) +
- 2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[5]) +
- ((limb) ((s32) in2[3])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[3])) +
- ((limb) ((s32) in2[4])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[4]);
- output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) +
- ((limb) ((s32) in2[7])) * ((s32) in[6]) +
- ((limb) ((s32) in2[5])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[5]) +
- ((limb) ((s32) in2[4])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[4]);
- output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
- ((limb) ((s32) in2[5])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[5])) +
- ((limb) ((s32) in2[6])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[6]);
- output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) +
- ((limb) ((s32) in2[8])) * ((s32) in[7]) +
- ((limb) ((s32) in2[6])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[6]);
- output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) +
- 2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[7]));
- output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) +
- ((limb) ((s32) in2[9])) * ((s32) in[8]);
- output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
-}
-
-/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */
-static void freduce_degree(limb *output) {
- /* Each of these shifts and adds ends up multiplying the value by 19. */
- output[8] += output[18] << 4;
- output[8] += output[18] << 1;
- output[8] += output[18];
- output[7] += output[17] << 4;
- output[7] += output[17] << 1;
- output[7] += output[17];
- output[6] += output[16] << 4;
- output[6] += output[16] << 1;
- output[6] += output[16];
- output[5] += output[15] << 4;
- output[5] += output[15] << 1;
- output[5] += output[15];
- output[4] += output[14] << 4;
- output[4] += output[14] << 1;
- output[4] += output[14];
- output[3] += output[13] << 4;
- output[3] += output[13] << 1;
- output[3] += output[13];
- output[2] += output[12] << 4;
- output[2] += output[12] << 1;
- output[2] += output[12];
- output[1] += output[11] << 4;
- output[1] += output[11] << 1;
- output[1] += output[11];
- output[0] += output[10] << 4;
- output[0] += output[10] << 1;
- output[0] += output[10];
-}
-
-#if (-1 & 3) != 3
-#error "This code only works on a two's complement system"
-#endif
-
-/* return v / 2^26, using only shifts and adds. */
-static limb div_by_2_26(const limb v)
-{
- /* High word of v; no shift needed*/
- const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
- /* Set to all 1s if v was negative; else set to 0s. */
- const int32_t sign = ((int32_t) highword) >> 31;
- /* Set to 0x3ffffff if v was negative; else set to 0. */
- const int32_t roundoff = ((uint32_t) sign) >> 6;
- /* Should return v / (1<<26) */
- return (v + roundoff) >> 26;
-}
-
-/* return v / (2^25), using only shifts and adds. */
-static limb div_by_2_25(const limb v)
-{
- /* High word of v; no shift needed*/
- const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
- /* Set to all 1s if v was negative; else set to 0s. */
- const int32_t sign = ((int32_t) highword) >> 31;
- /* Set to 0x1ffffff if v was negative; else set to 0. */
- const int32_t roundoff = ((uint32_t) sign) >> 7;
- /* Should return v / (1<<25) */
- return (v + roundoff) >> 25;
-}
-
-static s32 div_s32_by_2_25(const s32 v)
-{
- const s32 roundoff = ((uint32_t)(v >> 31)) >> 7;
- return (v + roundoff) >> 25;
-}
-
-/* Reduce all coefficients of the short form input so that |x| < 2^26.
- *
- * On entry: |output[i]| < 2^62
- */
-static void freduce_coefficients(limb *output) {
- unsigned i;
-
- output[10] = 0;
-
- for (i = 0; i < 10; i += 2) {
- limb over = div_by_2_26(output[i]);
- output[i] -= over << 26;
- output[i+1] += over;
-
- over = div_by_2_25(output[i+1]);
- output[i+1] -= over << 25;
- output[i+2] += over;
- }
- /* Now |output[10]| < 2 ^ 38 and all other coefficients are reduced. */
- output[0] += output[10] << 4;
- output[0] += output[10] << 1;
- output[0] += output[10];
-
- output[10] = 0;
-
- /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19 * 2^38
- * So |over| will be no more than 77825 */
- {
- limb over = div_by_2_26(output[0]);
- output[0] -= over << 26;
- output[1] += over;
- }
-
- /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 77825
- * So |over| will be no more than 1. */
- {
- /* output[1] fits in 32 bits, so we can use div_s32_by_2_25 here. */
- s32 over32 = div_s32_by_2_25((s32) output[1]);
- output[1] -= over32 << 25;
- output[2] += over32;
- }
-
- /* Finally, output[0,1,3..9] are reduced, and output[2] is "nearly reduced":
- * we have |output[2]| <= 2^26. This is good enough for all of our math,
- * but it will require an extra freduce_coefficients before fcontract. */
-}
-
-/* A helpful wrapper around fproduct: output = in * in2.
- *
- * output must be distinct to both inputs. The output is reduced degree and
- * reduced coefficient.
- */
-static void
-fmul(limb *output, const limb *in, const limb *in2) {
- limb t[19];
- fproduct(t, in, in2);
- freduce_degree(t);
- freduce_coefficients(t);
- memcpy(output, t, sizeof(limb) * 10);
-}
-
-static void fsquare_inner(limb *output, const limb *in) {
- output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
- output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
- output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
- ((limb) ((s32) in[0])) * ((s32) in[2]));
- output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
- ((limb) ((s32) in[0])) * ((s32) in[3]));
- output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) +
- 4 * ((limb) ((s32) in[1])) * ((s32) in[3]) +
- 2 * ((limb) ((s32) in[0])) * ((s32) in[4]);
- output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
- ((limb) ((s32) in[1])) * ((s32) in[4]) +
- ((limb) ((s32) in[0])) * ((s32) in[5]));
- output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
- ((limb) ((s32) in[2])) * ((s32) in[4]) +
- ((limb) ((s32) in[0])) * ((s32) in[6]) +
- 2 * ((limb) ((s32) in[1])) * ((s32) in[5]));
- output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
- ((limb) ((s32) in[2])) * ((s32) in[5]) +
- ((limb) ((s32) in[1])) * ((s32) in[6]) +
- ((limb) ((s32) in[0])) * ((s32) in[7]));
- output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) +
- 2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
- ((limb) ((s32) in[0])) * ((s32) in[8]) +
- 2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
- ((limb) ((s32) in[3])) * ((s32) in[5])));
- output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
- ((limb) ((s32) in[3])) * ((s32) in[6]) +
- ((limb) ((s32) in[2])) * ((s32) in[7]) +
- ((limb) ((s32) in[1])) * ((s32) in[8]) +
- ((limb) ((s32) in[0])) * ((s32) in[9]));
- output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
- ((limb) ((s32) in[4])) * ((s32) in[6]) +
- ((limb) ((s32) in[2])) * ((s32) in[8]) +
- 2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
- ((limb) ((s32) in[1])) * ((s32) in[9])));
- output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
- ((limb) ((s32) in[4])) * ((s32) in[7]) +
- ((limb) ((s32) in[3])) * ((s32) in[8]) +
- ((limb) ((s32) in[2])) * ((s32) in[9]));
- output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) +
- 2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
- 2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
- ((limb) ((s32) in[3])) * ((s32) in[9])));
- output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
- ((limb) ((s32) in[5])) * ((s32) in[8]) +
- ((limb) ((s32) in[4])) * ((s32) in[9]));
- output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
- ((limb) ((s32) in[6])) * ((s32) in[8]) +
- 2 * ((limb) ((s32) in[5])) * ((s32) in[9]));
- output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
- ((limb) ((s32) in[6])) * ((s32) in[9]));
- output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) +
- 4 * ((limb) ((s32) in[7])) * ((s32) in[9]);
- output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]);
- output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
-}
-
-static void
-fsquare(limb *output, const limb *in) {
- limb t[19];
- fsquare_inner(t, in);
- freduce_degree(t);
- freduce_coefficients(t);
- memcpy(output, t, sizeof(limb) * 10);
-}
-
-/* Take a little-endian, 32-byte number and expand it into polynomial form */
-static void
-fexpand(limb *output, const u8 *input) {
-#define F(n,start,shift,mask) \
- output[n] = ((((limb) input[start + 0]) | \
- ((limb) input[start + 1]) << 8 | \
- ((limb) input[start + 2]) << 16 | \
- ((limb) input[start + 3]) << 24) >> shift) & mask;
- F(0, 0, 0, 0x3ffffff);
- F(1, 3, 2, 0x1ffffff);
- F(2, 6, 3, 0x3ffffff);
- F(3, 9, 5, 0x1ffffff);
- F(4, 12, 6, 0x3ffffff);
- F(5, 16, 0, 0x1ffffff);
- F(6, 19, 1, 0x3ffffff);
- F(7, 22, 3, 0x1ffffff);
- F(8, 25, 4, 0x3ffffff);
- F(9, 28, 6, 0x1ffffff);
-#undef F
-}
-
-#if (-32 >> 1) != -16
-#error "This code only works when >> does sign-extension on negative numbers"
-#endif
-
-/* Take a fully reduced polynomial form number and contract it into a
- * little-endian, 32-byte array
- */
-static void
-fcontract(u8 *output, limb *input) {
- int i;
- int j;
-
- for (j = 0; j < 2; ++j) {
- for (i = 0; i < 9; ++i) {
- if ((i & 1) == 1) {
- /* This calculation is a time-invariant way to make input[i] positive
- by borrowing from the next-larger limb.
- */
- const s32 mask = (s32)(input[i]) >> 31;
- const s32 carry = -(((s32)(input[i]) & mask) >> 25);
- input[i] = (s32)(input[i]) + (carry << 25);
- input[i+1] = (s32)(input[i+1]) - carry;
- } else {
- const s32 mask = (s32)(input[i]) >> 31;
- const s32 carry = -(((s32)(input[i]) & mask) >> 26);
- input[i] = (s32)(input[i]) + (carry << 26);
- input[i+1] = (s32)(input[i+1]) - carry;
- }
- }
- {
- const s32 mask = (s32)(input[9]) >> 31;
- const s32 carry = -(((s32)(input[9]) & mask) >> 25);
- input[9] = (s32)(input[9]) + (carry << 25);
- input[0] = (s32)(input[0]) - (carry * 19);
- }
- }
-
- /* The first borrow-propagation pass above ended with every limb
- except (possibly) input[0] non-negative.
-
- Since each input limb except input[0] is decreased by at most 1
- by a borrow-propagation pass, the second borrow-propagation pass
- could only have wrapped around to decrease input[0] again if the
- first pass left input[0] negative *and* input[1] through input[9]
- were all zero. In that case, input[1] is now 2^25 - 1, and this
- last borrow-propagation step will leave input[1] non-negative.
- */
- {
- const s32 mask = (s32)(input[0]) >> 31;
- const s32 carry = -(((s32)(input[0]) & mask) >> 26);
- input[0] = (s32)(input[0]) + (carry << 26);
- input[1] = (s32)(input[1]) - carry;
- }
-
- /* Both passes through the above loop, plus the last 0-to-1 step, are
- necessary: if input[9] is -1 and input[0] through input[8] are 0,
- negative values will remain in the array until the end.
- */
-
- input[1] <<= 2;
- input[2] <<= 3;
- input[3] <<= 5;
- input[4] <<= 6;
- input[6] <<= 1;
- input[7] <<= 3;
- input[8] <<= 4;
- input[9] <<= 6;
-#define F(i, s) \
- output[s+0] |= input[i] & 0xff; \
- output[s+1] = (input[i] >> 8) & 0xff; \
- output[s+2] = (input[i] >> 16) & 0xff; \
- output[s+3] = (input[i] >> 24) & 0xff;
- output[0] = 0;
- output[16] = 0;
- F(0,0);
- F(1,3);
- F(2,6);
- F(3,9);
- F(4,12);
- F(5,16);
- F(6,19);
- F(7,22);
- F(8,25);
- F(9,28);
-#undef F
-}
-
-/* Input: Q, Q', Q-Q'
- * Output: 2Q, Q+Q'
- *
- * x2 z3: long form
- * x3 z3: long form
- * x z: short form, destroyed
- * xprime zprime: short form, destroyed
- * qmqp: short form, preserved
- */
-static void fmonty(limb *x2, limb *z2, /* output 2Q */
- limb *x3, limb *z3, /* output Q + Q' */
- limb *x, limb *z, /* input Q */
- limb *xprime, limb *zprime, /* input Q' */
- const limb *qmqp /* input Q - Q' */) {
- limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
- zzprime[19], zzzprime[19], xxxprime[19];
-
- memcpy(origx, x, 10 * sizeof(limb));
- fsum(x, z);
- fdifference(z, origx); /* does x - z */
-
- memcpy(origxprime, xprime, sizeof(limb) * 10);
- fsum(xprime, zprime);
- fdifference(zprime, origxprime);
- fproduct(xxprime, xprime, z);
- fproduct(zzprime, x, zprime);
- freduce_degree(xxprime);
- freduce_coefficients(xxprime);
- freduce_degree(zzprime);
- freduce_coefficients(zzprime);
- memcpy(origxprime, xxprime, sizeof(limb) * 10);
- fsum(xxprime, zzprime);
- fdifference(zzprime, origxprime);
- fsquare(xxxprime, xxprime);
- fsquare(zzzprime, zzprime);
- fproduct(zzprime, zzzprime, qmqp);
- freduce_degree(zzprime);
- freduce_coefficients(zzprime);
- memcpy(x3, xxxprime, sizeof(limb) * 10);
- memcpy(z3, zzprime, sizeof(limb) * 10);
-
- fsquare(xx, x);
- fsquare(zz, z);
- fproduct(x2, xx, zz);
- freduce_degree(x2);
- freduce_coefficients(x2);
- fdifference(zz, xx); /* does zz = xx - zz */
- memset(zzz + 10, 0, sizeof(limb) * 9);
- fscalar_product(zzz, zz, 121665);
- /* No need to call freduce_degree here:
- fscalar_product doesn't increase the degree of its input.
- */
- freduce_coefficients(zzz);
- fsum(zzz, xx);
- fproduct(z2, zz, zzz);
- freduce_degree(z2);
- freduce_coefficients(z2);
-}
-
-/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
- * them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid
- * side-channel attacks.
- *
- * NOTE that this function requires that 'iswap' be 1 or 0; other values give
- * wrong results. Also, the two limb arrays must be in reduced-coefficient,
- * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
- * and all all values in a[0..9],b[0..9] must have magnitude less than
- * INT32_MAX.
- */
-static void
-swap_conditional(limb a[19], limb b[19], limb iswap) {
- unsigned i;
- const s32 swap = (s32) -iswap;
-
- for (i = 0; i < 10; ++i) {
- const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
- a[i] = ((s32)a[i]) ^ x;
- b[i] = ((s32)b[i]) ^ x;
- }
-}
-
-/* Calculates nQ where Q is the x-coordinate of a point on the curve
- *
- * resultx/resultz: the x coordinate of the resulting curve point (short form)
- * n: a little endian, 32-byte number
- * q: a point of the curve (short form)
- */
-static void
-cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
- limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
- limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
- limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
- limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
-
- unsigned i, j;
-
- memcpy(nqpqx, q, sizeof(limb) * 10);
-
- for (i = 0; i < 32; ++i) {
- u8 byte = n[31 - i];
- for (j = 0; j < 8; ++j) {
- const limb bit = byte >> 7;
-
- swap_conditional(nqx, nqpqx, bit);
- swap_conditional(nqz, nqpqz, bit);
- fmonty(nqx2, nqz2,
- nqpqx2, nqpqz2,
- nqx, nqz,
- nqpqx, nqpqz,
- q);
- swap_conditional(nqx2, nqpqx2, bit);
- swap_conditional(nqz2, nqpqz2, bit);
-
- t = nqx;
- nqx = nqx2;
- nqx2 = t;
- t = nqz;
- nqz = nqz2;
- nqz2 = t;
- t = nqpqx;
- nqpqx = nqpqx2;
- nqpqx2 = t;
- t = nqpqz;
- nqpqz = nqpqz2;
- nqpqz2 = t;
-
- byte <<= 1;
- }
- }
-
- memcpy(resultx, nqx, sizeof(limb) * 10);
- memcpy(resultz, nqz, sizeof(limb) * 10);
-}
-
-/* -----------------------------------------------------------------------------
- * Shamelessly copied from djb's code
- * ----------------------------------------------------------------------------- */
-static void
-crecip(limb *out, const limb *z) {
- limb z2[10];
- limb z9[10];
- limb z11[10];
- limb z2_5_0[10];
- limb z2_10_0[10];
- limb z2_20_0[10];
- limb z2_50_0[10];
- limb z2_100_0[10];
- limb t0[10];
- limb t1[10];
- int i;
-
- /* 2 */ fsquare(z2,z);
- /* 4 */ fsquare(t1,z2);
- /* 8 */ fsquare(t0,t1);
- /* 9 */ fmul(z9,t0,z);
- /* 11 */ fmul(z11,z9,z2);
- /* 22 */ fsquare(t0,z11);
- /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
-
- /* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
- /* 2^7 - 2^2 */ fsquare(t1,t0);
- /* 2^8 - 2^3 */ fsquare(t0,t1);
- /* 2^9 - 2^4 */ fsquare(t1,t0);
- /* 2^10 - 2^5 */ fsquare(t0,t1);
- /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
-
- /* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
- /* 2^12 - 2^2 */ fsquare(t1,t0);
- /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
-
- /* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
- /* 2^22 - 2^2 */ fsquare(t1,t0);
- /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
-
- /* 2^41 - 2^1 */ fsquare(t1,t0);
- /* 2^42 - 2^2 */ fsquare(t0,t1);
- /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
- /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
-
- /* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
- /* 2^52 - 2^2 */ fsquare(t1,t0);
- /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
-
- /* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
- /* 2^102 - 2^2 */ fsquare(t0,t1);
- /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
- /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
-
- /* 2^201 - 2^1 */ fsquare(t0,t1);
- /* 2^202 - 2^2 */ fsquare(t1,t0);
- /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
- /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
-
- /* 2^251 - 2^1 */ fsquare(t1,t0);
- /* 2^252 - 2^2 */ fsquare(t0,t1);
- /* 2^253 - 2^3 */ fsquare(t1,t0);
- /* 2^254 - 2^4 */ fsquare(t0,t1);
- /* 2^255 - 2^5 */ fsquare(t1,t0);
- /* 2^255 - 21 */ fmul(out,t1,z11);
-}
-
-int curve25519_donna(u8 *, const u8 *, const u8 *);
-
-int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
- limb bp[10], x[10], z[11], zmone[10];
- uint8_t e[32];
- int i;
-
- for (i = 0; i < 32; ++i) e[i] = secret[i];
- e[0] &= 248;
- e[31] &= 127;
- e[31] |= 64;
-
- fexpand(bp, basepoint);
- cmult(x, z, e, bp);
- crecip(zmone, z);
- fmul(z, x, zmone);
- freduce_coefficients(z);
- fcontract(mypublic, z);
- return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/ec/ec.c b/jni/libzrtp/sources/bnlib/ec/ec.c
deleted file mode 100644
index 18e612f..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ec.c
+++ /dev/null
@@ -1,1695 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <bn.h>
-#include <bnprint.h>
-
-#include <ec/ec.h>
-
-static BigNum _mpiZero;
-static BigNum _mpiOne;
-static BigNum _mpiTwo;
-static BigNum _mpiThree;
-static BigNum _mpiFour;
-static BigNum _mpiEight;
-
-static BigNum* mpiZero = &_mpiZero;
-static BigNum* mpiOne = &_mpiOne;
-static BigNum* mpiTwo = &_mpiTwo;
-static BigNum* mpiThree = &_mpiThree;
-static BigNum* mpiFour = &_mpiFour;
-static BigNum* mpiEight = &_mpiEight;
-static int initialized = 0;
-
-
-/* The following parameters are given:
- - The prime modulus p
- - The order n
- - The 160-bit input seed SEED to the SHA-1 based algorithm (i.e., the domain parameter seed)
- - The output c of the SHA-1 based algorithm
- - The coefficient b (satisfying b2 c ≡ –27 (mod p))
- - The base point x coordinate Gx
- - The base point y coordinate Gy
-*/
-
-typedef struct _curveData {
- char *p;
- char *n;
- char *SEED;
- char *c;
- char *b;
- char *Gx;
- char *Gy;
-} curveData;
-
-static curveData nist192 = {
- "6277101735386680763835789423207666416083908700390324961279",
- "6277101735386680763835789423176059013767194773182842284081",
- "3045ae6fc8422f64ed579528d38120eae12196d5",
- "3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65",
- "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
- "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
- "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
-};
-
-static curveData nist224 = {
- "26959946667150639794667015087019630673557916260026308143510066298881",
- "26959946667150639794667015087019625940457807714424391721682722368061",
- "bd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5",
- "5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fb",
- "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
- "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
- "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
-};
-
-static curveData nist256 = {
- "115792089210356248762697446949407573530086143415290314195533631308867097853951",
- "115792089210356248762697446949407573529996955224135760342422259061068512044369",
- "c49d360886e704936a6678e1139d26b7819f7e90",
- "7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0d",
- "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
- "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
- "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
-};
-
-static curveData nist384 = {
- "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319",
- "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643",
- "a335926aa319a27a1d00896a6773a4827acdac73",
- "79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483",
- "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
- "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
- "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
-};
-
-static curveData nist521 = {
- "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151",
- "6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449",
- "d09e8800291cb85396cc6717393284aaa0da64ba",
- "0b48bfa5f420a34949539d2bdfc264eeeeb077688e44fbf0ad8f6d0edb37bd6b533281000518e19f1b9ffbe0fe9ed8a3c2200b8f875e523868c70c1e5bf55bad637",
- "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
- "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
- "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
-};
-
-
-/*
- * The data for curve3617 copied from:
- * http://safecurves.cr.yp.to/field.html
- * http://safecurves.cr.yp.to/base.html
- */
-static curveData curve3617 = {
- "3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef", /* Prime */
- "7ffffffffffffffffffffffffffffffffffffffffffffffffffeb3cc92414cf706022b36f1c0338ad63cf181b0e71a5e106af79", /* order */
- "", /* SEED */
- "", /* c */
- "", /* b */
- "1a334905141443300218c0631c326e5fcd46369f44c03ec7f57ff35498a4ab4d6d6ba111301a73faa8537c64c4fd3812f3cbc595", /* Gx*/
- "22", /* Gy (radix 16) */
-};
-
-/*
- * The data for curve25519 copied from:
- * http://safecurves.cr.yp.to/field.html
- * http://safecurves.cr.yp.to/base.html
- *
- * Note:
- * The data for Curve25519 is here for the sake of completeness and to have the same
- * set of initialization. One exception if the base point X coordinate (Gx) that we use to
- * compute the DH public value, refer to function ecdhGeneratePublic(...) in ecdh.c.
- *
- * Otherwise the functions use EcCurve structure only to get the pointers to the Curve25519
- * wrapper functions.
- *
- */
-static curveData curve25519 = {
- "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", /* Prime */
- "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", /* order */
- "", /* SEED */
- "", /* c */
- "", /* b */
- "9", /* Gx */
- "20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9", /* Gy */
-};
-
-/*============================================================================*/
-/* Bignum Shorthand Functions */
-/*============================================================================*/
-
-int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
-{
- bnAdd (rslt, n1);
- if (bnCmp (rslt, mod) >= 0) {
- bnSub (rslt, mod);
- }
- return 0;
-}
-
-int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
-{
- bnAddQ (rslt, n1);
- if (bnCmp (rslt, mod) >= 0) {
- bnSub (rslt, mod);
- }
- return 0;
-}
-
-int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
-{
- if (bnCmp (rslt, n1) < 0) {
- bnAdd (rslt, mod);
- }
- bnSub (rslt, n1);
- return 0;
-}
-
-int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
-{
- if (bnCmpQ (rslt, n1) < 0) {
- bnAdd (rslt, mod);
- }
- bnSubQ (rslt, n1);
- return 0;
-}
-
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve)
-{
- bnMul (rslt, n1, n2);
- if (curve)
- curve->modOp(rslt, rslt, mod);
- else
- bnMod(rslt, rslt, mod);
- return 0;
-}
-
-int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve)
-{
- bnMulQ (rslt, n1, n2);
- if (curve)
- curve->modOp(rslt, rslt, mod);
- else
- bnMod(rslt, rslt, mod);
- return 0;
-}
-
-int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve)
-{
- bnSquare (rslt, n1);
- if (curve)
- curve->modOp(rslt, rslt, mod);
- else
- bnMod(rslt, rslt, mod);
- return 0;
-}
-
-/*
- * Note on the Curve25519 functions and usage of BigNumber:
- * In most cases the functions to compute Curve25519 data are small wrapper functions
- * that implement the same API as for the other curve functions. The wrapper functions
- * then call the very specific, high-efficient function in curve25519-donna.c .
- *
- * For Curve25519 we don't have a real implementation for point add, point doubling, modulo
- * and check public key. Please refer to the actual implementations below.
- */
-
-static int ecGetAffineNist(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecGetAffineEd(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecGetAffine25519(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-static int ecDoublePointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecDoublePointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecDoublePoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-static int ecAddPointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-static int ecAddPointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-static int ecAddPoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-
-static int ecCheckPubKeyNist(const EcCurve *curve, const EcPoint *pub);
-static int ecCheckPubKey3617(const EcCurve *curve, const EcPoint *pub);
-static int ecCheckPubKey25519(const EcCurve *curve, const EcPoint *pub);
-
-static int ecGenerateRandomNumberNist(const EcCurve *curve, BigNum *d);
-static int ecGenerateRandomNumber3617(const EcCurve *curve, BigNum *d);
-static int ecGenerateRandomNumber25519(const EcCurve *curve, BigNum *d);
-
-static int ecMulPointScalarNormal(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-static int ecMulPointScalar25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-/* Forward declaration of new modulo functions for the EC curves */
-static int newMod192(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod256(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod384(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod521(BigNum *r, const BigNum *a, const BigNum *modulo);
-
-static int mod3617(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int mod25519(BigNum *r, const BigNum *a, const BigNum *modulo);
-
-static void commonInit()
-{
- bnBegin(mpiZero); bnSetQ(mpiZero, 0);
- bnBegin(mpiOne); bnSetQ(mpiOne, 1);
- bnBegin(mpiTwo); bnSetQ(mpiTwo, 2);
- bnBegin(mpiThree); bnSetQ(mpiThree, 3);
- bnBegin(mpiFour); bnSetQ(mpiFour, 4);
- bnBegin(mpiEight); bnSetQ(mpiEight, 8);
-}
-
-static void curveCommonInit(EcCurve *curve)
-{
- /* Initialize scratchpad variables and their pointers */
- bnBegin(&curve->_S1); curve->S1 = &curve->_S1;
- bnBegin(&curve->_U1); curve->U1 = &curve->_U1;
- bnBegin(&curve->_H); curve->H = &curve->_H;
- bnBegin(&curve->_R); curve->R = &curve->_R;
- bnBegin(&curve->_t0); curve->t0 = &curve->_t0;
- bnBegin(&curve->_t1); curve->t1 = &curve->_t1;
- bnBegin(&curve->_t2); curve->t2 = &curve->_t2;
- bnBegin(&curve->_t3); curve->t3 = &curve->_t3;
-}
-
-static void curveCommonPrealloc(EcCurve *curve)
-{
- size_t maxBits;
-
- /* variables must be able to hold p^2, plus one nimb (min. 15 bits) for overflow */
- maxBits = bnBits(curve->p) * 2 + 15;
-
- /* The set_bit allocates enough memory to hold maximum values */
- /* Initialize scratchpad variables before use */
- bnPrealloc(curve->S1, maxBits);
- bnPrealloc(curve->U1, maxBits);
- bnPrealloc(curve->H, maxBits);
- bnPrealloc(curve->R, maxBits);
- bnPrealloc(curve->S1, maxBits);
- bnPrealloc(curve->t1, maxBits);
- bnPrealloc(curve->t2, maxBits);
- bnPrealloc(curve->t3, maxBits);
-}
-
-int ecGetCurveNistECp(Curves curveId, EcCurve *curve)
-{
- curveData *cd;
-
- if (curveId >= Curve25519 && curveId <= Curve3617)
- return ecGetCurvesCurve(curveId, curve);
-
- if (!initialized) {
- commonInit();
- initialized = 1;
- }
- if (curve == NULL)
- return -2;
-
- bnBegin(&curve->_p); curve->p = &curve->_p;
- bnBegin(&curve->_n); curve->n = &curve->_n;
- bnBegin(&curve->_SEED); curve->SEED = &curve->_SEED;
- bnBegin(&curve->_c); curve->c = &curve->_c;
- bnBegin(&curve->_a); curve->a = &curve->_a;
- bnBegin(&curve->_b); curve->b = &curve->_b;
- bnBegin(&curve->_Gx); curve->Gx = &curve->_Gx;
- bnBegin(&curve->_Gy); curve->Gy = &curve->_Gy;
-
- curveCommonInit(curve);
-
- switch (curveId) {
- case NIST192P:
- cd = &nist192;
- curve->modOp = newMod192;
- break;
-
- case NIST224P:
- cd = &nist224;
- curve->modOp = bnMod;
- break;
-
- case NIST256P:
- cd = &nist256;
- curve->modOp = bnMod;
- break;
-
- case NIST384P:
- cd = &nist384;
- curve->modOp = newMod384;
- break;
-
- case NIST521P:
- cd = &nist521;
- curve->modOp = newMod521;
- break;
-
- default:
- return -2;
- }
-
- curve->affineOp = ecGetAffineNist;
- curve->doubleOp = ecDoublePointNist;
- curve->addOp = ecAddPointNist;
- curve->checkPubOp = ecCheckPubKeyNist;
- curve->randomOp = ecGenerateRandomNumberNist;
- curve->mulScalar = ecMulPointScalarNormal;
-
- bnReadAscii(curve->p, cd->p, 10);
- bnReadAscii(curve->n, cd->n, 10);
- bnReadAscii(curve->SEED, cd->SEED, 16);
- bnReadAscii(curve->c, cd->c, 16);
- bnCopy(curve->a, curve->p);
- bnSub(curve->a, mpiThree);
- bnReadAscii(curve->b, cd->b, 16);
- bnReadAscii(curve->Gx, cd->Gx, 16);
- bnReadAscii(curve->Gy, cd->Gy, 16);
-
- curveCommonPrealloc(curve);
- curve->id = curveId;
-
- return 0;
-}
-
-int ecGetCurvesCurve(Curves curveId, EcCurve *curve)
-{
- curveData *cd;
-
- if (!initialized) {
- commonInit();
- initialized = 1;
- }
- if (curve == NULL)
- return -2;
-
- /* set-up all bignum structures, simplifies "free" handling */
- bnBegin(&curve->_p); curve->p = &curve->_p;
- bnBegin(&curve->_n); curve->n = &curve->_n;
- bnBegin(&curve->_SEED); curve->SEED = &curve->_SEED;
- bnBegin(&curve->_c); curve->c = &curve->_c;
- bnBegin(&curve->_a); curve->a = &curve->_a;
- bnBegin(&curve->_b); curve->b = &curve->_b;
- bnBegin(&curve->_Gx); curve->Gx = &curve->_Gx;
- bnBegin(&curve->_Gy); curve->Gy = &curve->_Gy;
-
- curveCommonInit(curve);
-
- switch (curveId) {
- case Curve3617:
- cd = &curve3617;
- curve->modOp = mod3617;
- curve->affineOp = ecGetAffineEd;
- curve->doubleOp = ecDoublePointEd;
- curve->addOp = ecAddPointEd;
- curve->checkPubOp = ecCheckPubKey3617;
- curve->randomOp = ecGenerateRandomNumber3617;
- curve->mulScalar = ecMulPointScalarNormal;
-
- bnReadAscii(curve->a, "3617", 10);
- break;
-
- case Curve25519:
- cd = &curve25519;
- curve->modOp = mod25519;
- curve->affineOp = ecGetAffine25519;
- curve->doubleOp = ecDoublePoint25519;
- curve->addOp = ecAddPoint25519;
- curve->checkPubOp = ecCheckPubKey25519;
- curve->randomOp = ecGenerateRandomNumber25519;
- curve->mulScalar = ecMulPointScalar25519;
-
- bnReadAscii(curve->a, "486662", 10);
- break;
-
- default:
- return -2;
- }
- bnReadAscii(curve->p, cd->p, 16);
- bnReadAscii(curve->n, cd->n, 16);
-
- bnReadAscii(curve->Gx, cd->Gx, 16);
- bnReadAscii(curve->Gy, cd->Gy, 16);
-
- curveCommonPrealloc(curve);
- curve->id = curveId;
- return 0;
-}
-
-void ecFreeCurveNistECp(EcCurve *curve)
-{
- if (curve == NULL)
- return;
-
- bnEnd(curve->p);
- bnEnd(curve->n);
- bnEnd(curve->SEED);
- bnEnd(curve->c);
- bnEnd(curve->b);
- bnEnd(curve->Gx);
- bnEnd(curve->Gy);
-
- bnEnd(curve->S1);
- bnEnd(curve->U1);
- bnEnd(curve->H);
- bnEnd(curve->R);
- bnEnd(curve->t0);
- bnEnd(curve->t1);
- bnEnd(curve->t2);
- bnEnd(curve->t3);
-}
-
-/*
- * EC point helper functions
- */
-
-void ecInitPoint(EcPoint *P)
-{
- INIT_EC_POINT(P);
-}
-
-void ecFreePoint(EcPoint *P)
-{
- FREE_EC_POINT(P);
-}
-
-void ecSetBasePoint(EcCurve *C, EcPoint *P)
-{
- SET_EC_BASE_POINT(C, P);
-}
-
-void ecFreeCurvesCurve(EcCurve *curve)
-{
- ecFreeCurveNistECp(curve);
-}
-
-/*============================================================================*/
-/* Elliptic Curve arithmetic */
-/*============================================================================*/
-
-int ecGetAffine(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- return curve->affineOp(curve, R, P);
-}
-
-static int ecGetAffineNist(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- int ret = 0;
-
- struct BigNum z_1, z_2;
-
- bnBegin(&z_1);
- bnBegin(&z_2);
-
- /* affine x = X / Z^2 */
- bnInv (&z_1, P->z, curve->p); /* z_1 = Z^(-1) */
- bnMulMod_(&z_2, &z_1, &z_1, curve->p, curve); /* z_2 = Z^(-2) */
- bnMulMod_(R->x, P->x, &z_2, curve->p, curve);
-
- /* affine y = Y / Z^3 */
- bnMulMod_(&z_2, &z_2, &z_1, curve->p, curve); /* z_2 = Z^(-3) */
- bnMulMod_(R->y, P->y, &z_2, curve->p, curve);
-
- bnSetQ(R->z, 1);
-
- bnEnd(&z_1);
- bnEnd(&z_2);
- return ret;
-}
-
-static int ecGetAffineEd(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- int ret = 0;
-
- struct BigNum z_1;
-
- bnBegin(&z_1);
-
- /* affine x = X / Z */
- bnInv (&z_1, P->z, curve->p); /* z_1 = Z^(-1) */
- bnMulMod_(R->x, P->x, &z_1, curve->p, curve);
-
- /* affine y = Y / Z */
- bnMulMod_(R->y, P->y, &z_1, curve->p, curve);
-
- bnSetQ(R->z, 1);
-
- bnEnd(&z_1);
- return ret;
-
-}
-
-/*
- * If the arguments do not point to the same EcPoint then copy P to result.
- * Curve25519 has no specific GetAffine function, it's all inside curve25519-donna
- */
-static int ecGetAffine25519(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- if (R != P) {
- bnCopy(R->x, P->x);
- bnCopy(R->y, P->y);
- bnCopy(R->z, P->z);
- }
- return 0;
-}
-
-int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- return curve->doubleOp(curve, R, P);
-}
-
-static int ecDoublePointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- int ret = 0;
-
- EcPoint tP;
- const EcPoint *ptP = 0;
-
- if (!bnCmp(P->y, mpiZero) || !bnCmp(P->z, mpiZero)) {
- bnSetQ(R->x, 1);
- bnSetQ(R->y, 1);
- bnSetQ(R->z, 0);
- return 0;
- }
-
- /* Check for overlapping arguments, copy if necessary and set pointer */
- if (P == R) {
- INIT_EC_POINT(&tP);
- ptP = &tP;
- bnCopy(tP.x, P->x);
- bnCopy(tP.y, P->y);
- bnCopy(tP.z, P->z);
- }
- else
- ptP = P;
-
- /* S = 4*X*Y^2, save Y^2 in t1 for later use */
- bnMulMod_(curve->t1, ptP->y, ptP->y, curve->p, curve); /* t1 = Y^2 */
- bnMulMod_(curve->t0, ptP->x, mpiFour, curve->p, curve); /* t0 = 4 * X */
- bnMulMod_(curve->S1, curve->t0, curve->t1, curve->p, curve); /* S1 = t0 * t1 */
-
- /* M = 3*(X + Z^2)*(X - Z^2), use scratch variable U1 to store M value */
- bnMulMod_(curve->t2, ptP->z, ptP->z, curve->p, curve); /* t2 = Z^2 */
- bnCopy(curve->t0, ptP->x);
- bnAddMod_(curve->t0, curve->t2, curve->p); /* t0 = X + t2 */
- bnMulMod_(curve->t3, curve->t0, mpiThree, curve->p, curve); /* t3 = 3 * t0 */
- bnCopy(curve->t0, ptP->x);
- bnSubMod_(curve->t0, curve->t2, curve->p); /* t0 = X - t2 */
- bnMulMod_(curve->U1, curve->t3, curve->t0, curve->p, curve); /* M = t3 * t0 */
-
- /* X' = M^2 - 2*S */
- bnMulMod_(curve->t2, curve->U1, curve->U1, curve->p, curve); /* t2 = M^2 */
- bnMulMod_(curve->t0, curve->S1, mpiTwo, curve->p, curve); /* t0 = S * 2 */
- bnCopy(R->x, curve->t2);
- bnSubMod_(R->x, curve->t0, curve->p); /* X' = t2 - t0 */
-
- /* Y' = M*(S - X') - 8*Y^4 */
- bnMulMod_(curve->t3, curve->t1, curve->t1, curve->p, curve); /* t3 = Y^4 (t1 saved above) */
- bnMulMod_(curve->t2, curve->t3, mpiEight, curve->p, curve); /* t2 = t3 * 8 */
- bnCopy(curve->t3, curve->S1);
- bnSubMod_(curve->t3, R->x, curve->p); /* t3 = S - X' */
- bnMulMod_(curve->t0, curve->U1, curve->t3, curve->p, curve); /* t0 = M * t3 */
- bnCopy(R->y, curve->t0);
- bnSubMod_(R->y, curve->t2, curve->p); /* Y' = t0 - t2 */
-
- /* Z' = 2*Y*Z */
- bnMulMod_(curve->t0, ptP->y, mpiTwo, curve->p, curve); /* t0 = 2 * Y */
- bnMulMod_(R->z, curve->t0, ptP->z, curve->p, curve); /* Z' = to * Z */
-
- if (P == R)
- FREE_EC_POINT(&tP);
-
- return ret;
-}
-
-static int ecDoublePointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- EcPoint tP;
- const EcPoint *ptP = 0;
-
- /* Check for overlapping arguments, copy if necessary and set pointer */
- if (P == R) {
- INIT_EC_POINT(&tP);
- ptP = &tP;
- bnCopy(tP.x, P->x);
- bnCopy(tP.y, P->y);
- bnCopy(tP.z, P->z);
- }
- else
- ptP = P;
-
- /* Compute B, C, D, H, E */
- bnCopy(curve->t1, ptP->x);
- bnAddMod_(curve->t1, ptP->y, curve->p);
- bnSquareMod_(curve->t0, curve->t1, curve->p, curve); /* t0 -> B */
-
- bnSquareMod_(R->x, ptP->x, curve->p, curve); /* Rx -> C */
-
- bnSquareMod_(R->y, ptP->y, curve->p, curve); /* Ry -> D */
-
- bnSquareMod_(R->z, ptP->z, curve->p, curve); /* Rz -> H */
- bnAddMod_(R->z, R->z, curve->p); /* Rz -> 2H */
-
- bnCopy(curve->t1, R->x);
- bnAddMod_(curve->t1, R->y, curve->p); /* t1 -> E */
-
- /* Compute Ry */
- bnCopy(curve->t2, R->x);
- bnSubMod_(curve->t2, R->y, curve->p); /* C - D */
- bnMulMod_(R->y, curve->t1, curve->t2, curve->p, curve); /* E * t3; Ry */
-
- /* Compute Rx */
- bnSubMod_(curve->t0, curve->t1, curve->p); /* B - E; sub result */
- bnCopy(curve->t2, curve->t1);
- bnSubMod_(curve->t2, R->z, curve->p); /* t2 -> J; (E - 2H) */
- bnMulMod_(R->x, curve->t2, curve->t0, curve->p, curve); /* J * t0 */
-
- /* Compute Rz */
- bnMulMod_(R->z, curve->t2, curve->t1, curve->p, curve); /* J * E */
-
- if (P == R)
- FREE_EC_POINT(&tP);
-
- return 0;
-}
-
-/*
- * Curve25519 has no specific Double Point function, all inside curve25519-donna
- */
-static int ecDoublePoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
- return -2;
-}
-
-/* Add two elliptic curve points. Any of them may be the same object. */
-int ecAddPoint(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
- return curve->addOp(curve, R, P, Q);
-}
-
-static int ecAddPointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
- int ret = 0;
-
- EcPoint tP, tQ;
- const EcPoint *ptP = 0;
- const EcPoint *ptQ = 0;
-
-
- /* Fast check if application called add(R, P, P) */
- if (!bnCmp(P->x, Q->x) && !bnCmp(P->y, Q->y) && !bnCmp(P->z, Q->z)) {
- return ecDoublePoint(curve, R, P);
- }
-
- /* if P is (@,@), R = Q */
- if (!bnCmp(P->z, mpiZero)) {
- bnCopy(R->x, Q->x);
- bnCopy(R->y, Q->y);
- bnCopy(R->z, Q->z);
- return 0;
- }
-
- /* if Q is (@,@), R = P */
- if (!bnCmp(Q->z, mpiZero)) {
- bnCopy(R->x, P->x);
- bnCopy(R->y, P->y);
- bnCopy(R->z, P->z);
- return 0;
- }
-
- /* Check for overlapping arguments, copy if necessary and set pointers */
- if (P == R) {
- INIT_EC_POINT(&tP);
- ptP = &tP;
- bnCopy(tP.x, P->x);
- bnCopy(tP.y, P->y);
- bnCopy(tP.z, P->z);
- }
- else
- ptP = P;
-
- if (Q == R) {
- INIT_EC_POINT(&tQ);
- ptQ = &tQ;
- bnCopy(tQ.x, Q->x);
- bnCopy(tQ.y, Q->y);
- bnCopy(tQ.z, Q->z);
- }
- else
- ptQ = Q;
-
- /* U1 = X1*Z2^2, where X1: P->x, Z2: Q->z */
- bnMulMod_(curve->t1, ptQ->z, ptQ->z, curve->p, curve); /* t1 = Z2^2 */
- bnMulMod_(curve->U1, ptP->x, curve->t1, curve->p, curve); /* U1 = X1 * z_2 */
-
- /* S1 = Y1*Z2^3, where Y1: P->y */
- bnMulMod_(curve->t1, curve->t1, ptQ->z, curve->p, curve); /* t1 = Z2^3 */
- bnMulMod_(curve->S1, ptP->y, curve->t1, curve->p, curve); /* S1 = Y1 * z_2 */
-
- /* U2 = X2*Z1^2, where X2: Q->x, Z1: P->z */
- bnMulMod_(curve->t1, ptP->z, ptP->z, curve->p, curve); /* t1 = Z1^2 */
- bnMulMod_(curve->H, ptQ->x, curve->t1, curve->p, curve); /* H = X2 * t1 (store U2 in H) */
-
- /* H = U2 - U1 */
- bnSubMod_(curve->H, curve->U1, curve->p);
-
- /* S2 = Y2*Z1^3, where Y2: Q->y */
- bnMulMod_(curve->t1, curve->t1, ptP->z, curve->p, curve); /* t1 = Z1^3 */
- bnMulMod_(curve->R, ptQ->y, curve->t1, curve->p, curve); /* R = Y2 * t1 (store S2 in R) */
-
- /* R = S2 - S1 */
- bnSubMod_(curve->R, curve->S1, curve->p);
-
- /* if (U1 == U2), i.e H is zero */
- if (!bnCmp(curve->H, mpiZero)) {
-
- /* if (S1 != S2), i.e. R is _not_ zero: return infinity*/
- if (bnCmp(curve->R, mpiZero)) {
- bnSetQ(R->x, 1);
- bnSetQ(R->y, 1);
- bnSetQ(R->z, 0);
- return 0;
- }
- return ecDoublePoint(curve, R, P);
- }
- /* X3 = R^2 - H^3 - 2*U1*H^2, where X3: R->x */
- bnMulMod_(curve->t0, curve->H, curve->H, curve->p, curve); /* t0 = H^2 */
- bnMulMod_(curve->t1, curve->U1, curve->t0, curve->p, curve); /* t1 = U1 * t0, (hold t1) */
- bnMulMod_(curve->t0, curve->t0, curve->H, curve->p, curve); /* t0 = H^3, (hold t0) */
- bnMulMod_(curve->t2, curve->R, curve->R, curve->p, curve); /* t2 = R^2 */
- bnCopy(curve->t3, curve->t2);
- bnSubMod_(curve->t3, curve->t0, curve->p); /* t3 = t2 - t0, (-H^3)*/
- bnMulMod_(curve->t2, mpiTwo, curve->t1, curve->p, curve); /* t2 = 2 * t1 */
- bnCopy(R->x, curve->t3);
- bnSubMod_(R->x, curve->t2, curve->p); /* X3 = t3 - t2 */
-
- /* Y3 = R*(U1*H^2 - X3) - S1*H^3, where Y3: R->y */
- bnSubMod_(curve->t1, R->x, curve->p); /* t1 = t1 - X3, overwrites t1 now */
- bnMulMod_(curve->t2, curve->R, curve->t1, curve->p, curve); /* t2 = R * z_2 */
- bnMulMod_(curve->S1, curve->S1, curve->t0, curve->p, curve); /* S1 = S1 * t0, (t0 has H^3) */
- bnCopy(R->y, curve->t2);
- bnSubMod_(R->y, curve->S1, curve->p); /* Y3 = t2 - S1 */
-
- /* Z3 = H*Z1*Z2, where Z1: P->z, Z2: Q->z, Z3: R->z */
- bnMulMod_(curve->t2, curve->H, P->z, curve->p, curve); /* t2 = H * Z1 */
- bnMulMod_(R->z, curve->t2, Q->z, curve->p, curve); /* Z3 = t2 * Z2 */
-
- if (P == R)
- FREE_EC_POINT(&tP);
- if (Q == R)
- FREE_EC_POINT(&tQ);
- return ret;
-}
-
-/*
- * Refer to the document: Faster addition and doubling on elliptic curves; Daniel J. Bernstein and Tanja Lange
- * section 4.
- *
- * This function is a variant of the 'addition'. The function returns the result in an own curve point
- * and does not overwrite its input parameters.
- */
-static int ecAddPointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
- EcPoint tP, tQ;
- const EcPoint *ptP = 0;
- const EcPoint *ptQ = 0;
-
- /* if P is (@,@), R = Q */
- if (!bnCmp(P->z, mpiZero)) {
- bnCopy(R->x, Q->x);
- bnCopy(R->y, Q->y);
- bnCopy(R->z, Q->z);
- return 0;
- }
-
- /* if Q is (@,@), R = P */
- if (!bnCmp(Q->z, mpiZero)) {
- bnCopy(R->x, P->x);
- bnCopy(R->y, P->y);
- bnCopy(R->z, P->z);
- return 0;
- }
-
- /* Check for overlapping arguments, copy if necessary and set pointers */
- if (P == R) {
- INIT_EC_POINT(&tP);
- ptP = &tP;
- bnCopy(tP.x, P->x);
- bnCopy(tP.y, P->y);
- bnCopy(tP.z, P->z);
- }
- else
- ptP = P;
-
- if (Q == R) {
- INIT_EC_POINT(&tQ);
- ptQ = &tQ;
- bnCopy(tQ.x, Q->x);
- bnCopy(tQ.y, Q->y);
- bnCopy(tQ.z, Q->z);
- }
- else
- ptQ = Q;
-
- /* Compute A, C, D first */
- bnMulMod_(R->z, ptP->z, ptQ->z, curve->p, curve); /* Rz -> A; (Z1 * z2); Rz becomes R3 */
- bnMulMod_(R->x, ptP->x, ptQ->x, curve->p, curve); /* Rx -> C; (X1 * X2); Rx becomes R1 */
- bnMulMod_(R->y, ptP->y, ptQ->y, curve->p, curve); /* Ry -> D; (Y1 * Y2); Ry becomes R2 */
-
- /* Compute large parts of X3 equation, sub result in t0 */
- bnCopy(curve->t0, ptP->x);
- bnAddMod_(curve->t0, ptP->y, curve->p); /* t0 -> X1 + Y1 */
- bnCopy(curve->t1, ptQ->x);
- bnAddMod_(curve->t1, ptQ->y, curve->p); /* t1 -> X2 + Y2 */
- bnMulMod_(curve->t2, curve->t0, curve->t1, curve->p, curve); /* t2 = t0 * t1 */
- bnSubMod_(curve->t2, R->x, curve->p); /* t2 - C */
- bnSubMod_(curve->t2, R->y, curve->p); /* t2 - D */
- bnMulMod_(curve->t0, curve->t2, R->z, curve->p, curve); /* t0 -> R7; (t2 * A); sub result */
-
- /* Compute E */
- bnMulMod_(curve->t2, R->x, R->y, curve->p, curve); /* t2 = C * D */
- bnMulMod_(curve->t1, curve->t2, curve->a, curve->p, curve); /* t1 -> E; t1 new R8 */
-
- /* Compute part of Y3 equation, sub result in t2 */
- bnSubMod_(R->y, R->x, curve->p); /* Ry = D - C; sub result */
- bnMulMod_(curve->t2, R->y, R->z, curve->p, curve); /* t2 = Ry * A; sub result */
-
- /* Compute B */
- bnSquareMod_(R->z, R->z, curve->p, curve); /* Rz -> B; (A^2) */
-
- /* Compute F */
- bnCopy(curve->t3, R->z);
- bnSubMod_(curve->t3, curve->t1, curve->p); /* t3 -> F; (B - E) */
-
- /* Compute G */
- bnAddMod_(R->z, curve->t1, curve->p); /* Rz -> G; (B + E) */
-
- /* Compute, X, Y, Z results */
- bnMulMod_(R->x, curve->t3, curve->t0, curve->p, curve); /* Rx = F * t0 */
- bnMulMod_(R->y, curve->t2, R->z, curve->p, curve); /* Ry = t2 * G */
- bnMulMod_(R->z, curve->t3, R->z, curve->p, curve); /* Rz = F * G */
-
- if (P == R)
- FREE_EC_POINT(&tP);
- if (Q == R)
- FREE_EC_POINT(&tQ);
-
- return 0;
-}
-
-/*
- * Curve25519 has no specific Add Point function, all inside curve25519-donna
- */
-static int ecAddPoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
- return -2;
-}
-
-int ecMulPointScalar(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
- return curve->mulScalar(curve, R, P, scalar);
-}
-
-static int ecMulPointScalarNormal(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
- int ret = 0;
- int i;
- int bits = bnBits(scalar);
- EcPoint n;
-
- INIT_EC_POINT(&n);
- bnCopy(n.x, P->x);
- bnCopy(n.y, P->y);
- bnCopy(n.z, P->z);
-
- bnSetQ(R->x, 0);
- bnSetQ(R->y, 0);
- bnSetQ(R->z, 0);
-
- for (i = 0; i < bits; i++) {
- if (bnReadBit(scalar, i))
- ecAddPoint(curve, R, R, &n);
-
- /* ecAddPoint(curve, &n, &n, &n); */
- ecDoublePoint(curve, &n, &n);
- }
- FREE_EC_POINT(&n);
- return ret;
-}
-
-/*
- * This function uses BigNumber only as containers to transport the 32 byte data.
- * This makes it compliant to the other functions and thus higher-level API does not change.
- *
- * curve25519_donna function uses data in little endian format.
- */
-static int ecMulPointScalar25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
- uint8_t basepoint[32], secret[32], result[32];
-
- bnExtractLittleBytes(P->x, basepoint, 0, 32); /* 25519 function requires the X coordinate only (compressed) */
- bnExtractLittleBytes(scalar, secret, 0, 32);
- curve25519_donna(result, secret, basepoint);
- bnInsertLittleBytes(R->x, result, 0, 32);
- return 0;
-}
-
-#ifdef WEAKRANDOM
-#include <fcntl.h>
-
-/*
- * A standard random number generator that uses the portable random() system function.
- *
- * This should be enhanced to use a better random generator
- */
-static int _random(unsigned char *output, size_t len)
-{
- size_t num = 0;
-
- int rnd = open("/dev/urandom", O_RDONLY);
- if (rnd >= 0) {
- num = read(rnd, output, len);
- close(rnd);
- }
- else
- return num;
-
- return( 0 );
-}
-#else
-#include <cryptcommon/ZrtpRandom.h>
-static int _random(unsigned char *output, size_t len)
-{
- return zrtp_getRandomData(output, len);
-}
-#endif
-
-int ecGenerateRandomNumber(const EcCurve *curve, BigNum *d)
-{
- return curve->randomOp(curve, d);
-}
-
-static int ecGenerateRandomNumberNist(const EcCurve *curve, BigNum *d)
-{
- BigNum c, nMinusOne;
-
- size_t randomBytes = ((bnBits(curve->n) + 64) + 7) / 8;
-
- uint8_t *ran = malloc(randomBytes);
-
- bnBegin(&c);
- bnBegin(&nMinusOne);
-
- bnCopy(&nMinusOne, curve->n);
- bnSubMod_(&nMinusOne, mpiOne, curve->p);
-
- bnSetQ(d, 0);
-
- while (!bnCmpQ(d, 0)) {
- /* use _random function */
- _random(ran, randomBytes);
- bnInsertBigBytes(&c, ran, 0, randomBytes);
- bnMod(d, &c, &nMinusOne);
- bnAddMod_(d, mpiOne, curve->p);
- }
-
- bnEnd(&c);
- bnEnd(&nMinusOne);
- free(ran);
-
- return 0;
-}
-
-static int ecGenerateRandomNumber3617(const EcCurve *curve, BigNum *d)
-{
- unsigned char random[52];
- _random(random, 52);
-
- /* prepare the secret random data: clear bottom 3 bits. Clearing top 2 bits
- * makes is a 414 bit value
- */
- random[51] &= ~0x7;
- random[0] &= 0x3f;
- /* convert the random data into big numbers */
- bnInsertBigBytes(d, random, 0, 52);
- return 0;
-}
-
-static int ecGenerateRandomNumber25519(const EcCurve *curve, BigNum *d)
-{
- unsigned char random[32];
- _random(random, 32);
-
- /* No specific preparation. The curve25519_donna functions prepares the data.
- *
- * convert the random data into big numbers. the bigNumber is a container only.
- * we don not use the big number for any arithmetic
- */
- bnInsertLittleBytes(d, random, 0, 32);
- return 0;
-
-}
-
-int ecCheckPubKey(const EcCurve *curve, const EcPoint *pub)
-{
- return curve->checkPubOp(curve, pub);
-}
-
-static int ecCheckPubKeyNist(const NistECpCurve *curve, const EcPoint *pub)
-{
- /* Represent point at infinity by (0, 0), make sure it's not that */
- if (bnCmpQ(pub->x, 0) == 0 && bnCmpQ(pub->y, 0) == 0) {
- return 0;
- }
- /* Check that coordinates are within range */
- if (bnCmpQ(pub->x, 0) < 0 || bnCmp(pub->x, curve->p) >= 0) {
- return 0;
- }
- if (bnCmpQ(pub->y, 0) < 0 || bnCmp(pub->y, curve->p) >= 0) {
- return 0;
- }
- /* Check that point satisfies EC equation y^2 = x^3 - 3x + b, mod P */
- bnSquareMod_(curve->t1, pub->y, curve->p, curve);
- bnSquareMod_(curve->t2, pub->x, curve->p, curve);
- bnSubQMod_(curve->t2, 3, curve->p);
- bnMulMod_(curve->t2, curve->t2, pub->x, curve->p, curve);
- bnAddMod_(curve->t2, curve->b, curve->p);
- if (bnCmp (curve->t1, curve->t2) != 0) {
- return 0;
- }
- return 1;
-
-}
-
-static int ecCheckPubKey3617(const EcCurve *curve, const EcPoint *pub)
-{
- /* Represent point at infinity by (0, 0), make sure it's not that */
- if (bnCmpQ(pub->x, 0) == 0 && bnCmpQ(pub->y, 0) == 0) {
- return 0;
- }
- /* Check that coordinates are within range */
- if (bnCmpQ(pub->x, 0) < 0 || bnCmp(pub->x, curve->p) >= 0) {
- return 0;
- }
- if (bnCmpQ(pub->y, 0) < 0 || bnCmp(pub->y, curve->p) >= 0) {
- return 0;
- }
- /* Check that point satisfies EC equation x^2+y^2 = 1+3617x^2y^2, mod P */
- bnSquareMod_(curve->t1, pub->y, curve->p, curve);
- bnSquareMod_(curve->t2, pub->x, curve->p, curve);
- bnCopy(curve->t3, curve->t1); /* Load t3 */
- bnAddMod_(curve->t3, curve->t2, curve->p); /* t3 = t1 + t2, (x^2+y^2)*/
-
- bnMulMod_(curve->t0, curve->a, curve->t1, curve->p, curve); /* t0 = a * t1, (3617 * x^2) */
- bnMulMod_(curve->t0, curve->t0, curve->t2, curve->p, curve); /* t0 = t0 * t1, (3617 * x^2 * y^2) */
- bnAddMod_(curve->t0, mpiOne, curve->p); /* t0 = t0 + 1, (3617 * x^2 * y^2 + 1) */
-
- if (bnCmp (curve->t0, curve->t3) != 0) {
- return 0;
- }
- return 1;
-}
-
-/**
- * According to http://cr.yp.to/ecdh.html#validate no validation is required if used for Diffie-Hellman
- * thus always return success.
- */
-static int ecCheckPubKey25519(const EcCurve *curve, const EcPoint *pub)
-{
- return 1;
-}
-
-static int mod3617(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- unsigned char buffer[52] = {0};
- int cmp;
- BigNum tmp;
-
- bnBegin(&tmp);
- cmp = bnCmp(modulo, a);
- if (cmp == 0) { /* a is equal modulo, set resul to zero */
- bnSetQ(r, 0);
- return 0;
- }
- if (cmp > 0) { /* modulo is greater than a - copy a to r and return it */
- bnCopy(r, a);
- return 0;
- }
- bnExtractLittleBytes(a, buffer, 0, 52);
- buffer[51] &= 0x3f;
-
- bnCopy(&tmp, a);
- bnRShift(&tmp, 414);
- bnCopy(r, &tmp);
- bnLShift(r, 4);
- bnAdd(r, &tmp);
-
- bnInsertLittleBytes(&tmp, buffer, 0, 52);
-
- bnAdd(r, &tmp);
- while (bnCmp(r, modulo) >= 0) {
- bnSub(r, modulo);
- }
- bnEnd(&tmp);
- return 0;
-}
-
-/*
- * Curve25519 has no specific modulo function, all inside curve25519-donna
- */
-static int mod25519(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- return -2;
-}
-
-/*
- * Beware: Here are the dragons.
- *
- * The modulo implementations for the NIST curves. For more detailled information see
- * FIPS 186-3, chapter D.2 and other papers about Generailzed Mersenne numbers.
- *
- * I use byte operations to perfom the additions with carry. On a little endian machine
- * this saves conversion from/to big endian format if I would use integers for example. Also
- * using byte addition into a short carry accumulator works on every word size and avoids
- * complex testing and handling of wordsizes and big/little endian stuff.
- *
- */
-
-/* new modulo for 192bit curve */
-static int newMod192(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- unsigned char buffer[200] = {0};
- unsigned char *pt;
- unsigned char *ps1;
- unsigned char *ps2;
- unsigned char *ps3;
- short ac;
- int cmp;
-
- /* Binary big number representation in PolarSSL is always big endian
- *
- * the least significant 64bit large word starts at byte offset 40,
- * the least significant 32bit word starts at byte offset 44
- * the least significant byte starts at byte offset 47
- *
- * S3 S2 S1 T
- * /-----^------\
- * A5 A4 A3 A2 A1 A0
- * 64bit 0 1 2 3 4 5
- * |--+--|--+--|--+--|--+--|--+--|--+--|
- * 32bit 0 1 2 3 4 5 6 7 8 9 10 11
- *
- * perform T + S1 + S2 + S3 mod p
-
- * where T = (A2 || A1 || A0)
- * + S1 = ( 0 || A3 || A3)
- * + S2 = (A4 || A4 || 0)
- * + S3 = (A5 || A5 || A5)
- *
- * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
- */
-
- /* TODO: check if a is > modulo^2 */
- cmp = bnCmp(modulo, a);
- if (cmp == 0) { /* a is equal modulo, set resul to zero */
- bnSetQ(r, 0);
- return 0;
- }
- if (cmp > 0) { /* modulo is greater than a - copy a to r and return it */
- bnCopy(r, a);
- return 0;
- }
- bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
- /* 6 'A' words, each word is 8 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((6-X)*8)-1)
-
- ac = 0;
-
- pt = A(0); /* pt points to least significant byte of A0 */
-
- /* Add up first 8 byte word, no need to add ps2 */
- ps1 = A(3); /* ps1 points to least significant byte of S1 (A3) */
- ps3 = A(5); /* ps3 points to least significant byte of S3 (A5)*/
-
- /* Each block processes one 32 bit word, big endian, using byte operations */
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- /* Add up second 8 byte word, all three S words are used here */
- ps1 = A(3); ps2 = A(4); ps3 = A(5);
-
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- /* Add up third 8 byte word, no need to add S1 word */
- ps2 = A(4); ps3 = A(5);
-
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
- /* In this function we cannot have a negative carry and at most a carry of 2
- * thus just subtract the modulo until we are less than modulo
- */
- bnSetQ(r, 0);
-
- *(A(3)) = ac; /* Store the carry */
- bnInsertBigBytes(r, A(3), 0, 25); /* 25: 3 * 8 byte words + 1 carry byte */
- while (bnCmp(r, modulo) >= 0) {
- bnSub(r, modulo);
- }
- return 0;
-}
-#undef A
-
-/* new modulo for 256bit curve */
-static int newMod256(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- unsigned char buffer[200] = {0};
- unsigned char *pt;
- unsigned char *ps1;
- unsigned char *ps2;
- unsigned char *ps3;
- unsigned char *ps4;
-
- unsigned char *pd1;
- unsigned char *pd2;
- unsigned char *pd3;
- unsigned char *pd4;
- short ac;
- int cmp;
-
- /* Binary big number representation in PolarSSL is always big endian
- *
- * the least significant byte starts at byte offset 63
- *
- * T
- * /-----------------^------------------\
- * A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
- * |----+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|
- * offset 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64
- *
- * T = ( A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0 )
- *
- * S1 = ( A15 || A14 || A13 || A12 || A11 || 00 || 00 || 00 )
- * S2 = ( 00 || A15 || A14 || A13 || A12 || 00 || 00 || 00 )
- * S3 = ( A15 || A14 || 00 || 00 || 00 || A10 || A9 || A8 )
- * S4 = ( A8 || A13 || A15 || A14 || A13 || A11 || A10 || A9 )
- * D1 = ( A10 || A8 || 00 || 00 || 00 || A13 || A12 || A11 )
- * D2 = ( A11 || A9 || 00 || 00 || A15 || A14 || A13 || A12 )
- * D3 = ( A12 || 00 || A10 || A9 || A8 || A15 || A14 || A13 )
- * D4 = ( A13 || 00 || A11 || A10 || A9 || 00 || A15 || A14 )
- *
- * perform B = T + 2*S1 + 2*S2 + S3 + S4 - D1 - D2 - D3 - D4 mod p
- *
- * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
- */
-
- cmp = bnCmp(modulo, a);
- if (cmp == 0) { /* a is equal modulo, set resul to zero */
- bnSetQ(r, 0);
- return 0;
- }
- if (cmp > 0) { /* modulo is greater than a - copya to r and return it */
- bnCopy(r, a);
- return 0;
- }
- bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
- /* 16 'A' words, each word is 4 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((16-X)*4)-1)
-
- ac = 0;
-
- pt = A(0); /* pt points to least significant byte of A0 */
-
- /* Set up to add up data that goes into A0 (right-most column abover); S1, S2 not used */
- ps3 = A(8); /* ps3 points to least significant byte of S3 */
- ps4 = A(9); /* ps4 points to least significant byte of S4 */
- pd1 = A(11); /* pd1 points to least significant byte of D1 */
- pd2 = A(12); /* pd2 points to least significant byte of D2 */
- pd3 = A(13); /* pd3 points to least significant byte of D3 */
- pd4 = A(14); /* pd4 points to least significant byte of D4 */
-
- /* Each block processes one 32 bit word, big endian, using byte operations */
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A1; S1, S2 not used */
- ps3 = A(9); ps4 = A(10); pd1 = A(12); pd2 = A(13); pd3 = A(14); pd4 = A(15);
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A2; S1, S2, D4 not used */
- ps3 = A(10); ps4 = A(11); pd1 = A(13); pd2 = A(14); pd3 = A(15);
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A3; S3, D1 not used */
- ps1 = A(11); ps2 = A(12); ps4 = A(13); pd2 = A(15); pd3 = A(8); pd4 = A(9);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A4; S3, D1, D2 not used */
- ps1 = A(12); ps2 = A(13); ps4 = A(14); pd3 = A(9); pd4 = A(10);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A5; S3, D1, D2 not used */
- ps1 = A(13); ps2 = A(14); ps4 = A(15); pd3 = A(10); pd4 = A(11);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A6; D3, D4 not used */
- ps1 = A(14); ps2 = A(15); ps3 = A(14); ps4 = A(13); pd1 = A(8); pd2 = A(9);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2;ac += *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add up data that goes into A7; S2 not used */
- ps1 = A(15); ps3 = A(15); ps4 = A(8); pd1 = A(10); pd2 = A(11); pd3 = A(12); pd4 = A(13);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
- bnSetQ(r, 0);
- if (ac > 0) {
- *(A(8)) = ac; /* Store the carry */
- bnInsertBigBytes(r, A(8), 0, 33); /* 33: 8 * 4 byte words + 1 carry byte */
- }
- /* Negative carry requires that we add the modulo (carry * -1) times to make
- * the result positive. Then get the result mod(256).
- */
- else if (ac < 0) {
- int msb, maxMsb;
-
- *(A(8)) = 0;
- bnInsertBigBytes(r, A(8), 0, 33); /* 33: 8 * 4 byte words + 1 carry byte */
- ac *= -1;
- while (ac--) {
- bnAdd(r, modulo);
- }
- maxMsb = bnBits(modulo);
- msb = bnBits(r) - maxMsb;
- /* clear all bits above bit length of modulo. This length is 256 here, thus
- * we effectiviely doing a mod(256)
- */
- if (msb > 0) {
- BigNum tmp;
- bnBegin(&tmp);
- bnSetQ (&tmp, 1);
- bnLShift (&tmp, maxMsb);
- bnMod(r, r, &tmp);
- bnEnd(&tmp);
- }
- }
- else {
- *(A(8)) = 0;
- bnInsertBigBytes(r, A(8), 0, 33); /* 33: 8 * 4 byte words + 1 carry byte */
- }
- while (bnCmp(r, modulo) >= 0) {
- bnSub(r, modulo);
- }
- return 0;
-}
-#undef A
-
-
-/* new modulo for 384bit curve */
-static int newMod384(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- unsigned char buffer[200] = {0};
- unsigned char *pt;
- unsigned char *ps1;
- unsigned char *ps2;
- unsigned char *ps3;
- unsigned char *ps4;
- unsigned char *ps5;
- unsigned char *ps6;
-
- unsigned char *pd1;
- unsigned char *pd2;
- unsigned char *pd3;
- short ac;
- int cmp;
-
- /*
- *
- * the least significant byte starts at byte offset 97
- *
- * T
- * /---------------------------^----------------------------\
- * A23 ......... A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
- * |----+ ...... |----+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|
- *
- * T = (A11 || A10 || A9 || A8 || A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0)
-
- * S1 = ( 00 || 00 || 00 || 00 || 00 || A23 || A22 || A21 || 00 || 00 || 00 || 00)
- * S2 = (A23 || A22 || A21 || A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12)
- * S3 = (A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A23 || A22 || A21)
- * S4 = (A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A20 || 00 || A23 || 00)
- * S5 = ( 00 || 00 || 00 || 00 || A23 || A22 || A21 || A20 || 00 || 00 || 00 || 00)
- * S6 = ( 00 || 00 || 00 || 00 || 00 || 00 || A23 || A22 || A21 || 00 || 00 || A20)
- * D1 = (A22 || A21 || A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A23)
- * D2 = ( 00 || 00 || 00 || 00 || 00 || 00 || 00 || A23 || A22 || A21 || A20 || 00)
- * D3 = ( 00 || 00 || 00 || 00 || 00 || 00 || 00 || A23 || A23 || 00 || 00 || 00)
- *
- * perform B = T + 2S1 + S2 + S3 + S4 + S5 + S6 – D1 – D2 – D3 mod p
- *
- * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
- * optimize if input is already < modulo (just copy over in this case).
- */
-
- cmp = bnCmp(modulo, a);
- if (cmp == 0) { /* a is equal modulo, set resul to zero */
- bnSetQ(r, 0);
- return 0;
- }
- if (cmp > 0) { /* modulo is greater than a - copy a to r and return it */
- bnCopy(r, a);
- return 0;
- }
-
- bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
- /* 24 'A' words, each word is 4 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((24-X)*4)-1)
-
- ac = 0;
-
- pt = A(0); /* pt points to least significant byte of A0 */
-
- /* Set up to add data that goes into A0; S1, S4, S5, D2, D3 not used */
- ps2 = A(12); ps3 = A(21); ps6 = A(20); pd1 = A(23);
-
- /* Each block processes one 32 bit word, big endian, using byte operations */
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A1; S1, S5, S6, D3 not used */
- ps2 = A(13); ps3 = A(22); ps4 = A(23); pd1= A(12); pd2 = A(20);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A2; S1, S4, S5, S6, D3 not used */
- ps2 = A(14); ps3 = A(23); pd1 = A(13); pd2 = A(21);
- ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A3; S1, S5, S6 not used */
- ps2 = A(15); ps3 = A(12); ps4 = A(20); ps6 = A(21); pd1 = A(14); pd2 = A(22); pd3 = A(23);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A4 */
- ps1 = A(21); ps2 = A(16); ps3 = A(13); ps4 = A(12); ps5 = A(20); ps6 = A(22); pd1 = A(15); pd2 = A(23), pd3 = A(23);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A5; D2, D3 not used */
- ps1 = A(22); ps2 = A(17); ps3 = A(14); ps4 = A(13); ps5 = A(21); ps6 = A(23); pd1 = A(16);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A6; S6, D2, D3 not used */
- ps1 = A(23); ps2 = A(18); ps3 = A(15); ps4 = A(14); ps5 = A(22); pd1 = A(17);
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A7; S1, S6, D2, D3 not used */
- ps2 = A(19); ps3 = A(16); ps4 = A(15); ps5 = A(23); pd1 = A(18);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A8; S1, S5, S6, D2, D3 not used */
- ps2 = A(20); ps3 = A(17); ps4 = A(16); pd1 = A(19);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A9; S1, S5, S6, D2, D3 not used */
- ps2 = A(21); ps3 = A(18); ps4 = A(17); pd1 = A(20);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A10; S1, S5, S6, D2, D3 not used */
- ps2 = A(22); ps3 = A(19); ps4 = A(18); pd1 = A(21);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- /* Set up to add data that goes into A10; S1, S5, S6, D2, D3 not used */
- ps2 = A(23); ps3 = A(20); ps4 = A(19); pd1 = A(22);
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
- ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
- bnSetQ(r, 0);
- if (ac > 0) {
- *(A(12)) = ac; /* Store the carry */
- bnInsertBigBytes(r, A(12), 0, 49); /* 49: 12 * 4 byte words + 1 carry byte */
- }
- /* Negative carry requires that we add the modulo (carry * -1) times to make
- * the result positive. Then get the result mod(256).
- */
- else if (ac < 0) {
- int msb, maxMsb;
-
- *(A(12)) = 0;
- bnInsertBigBytes(r, A(12), 0, 49); /* 49: 12 * 4 byte words + 1 carry byte */
- ac *= -1;
- while (ac--) {
- bnAdd(r, modulo);
- }
- maxMsb = bnBits(modulo);
- msb = bnBits(r) - maxMsb;
- /* clear all bits above bit length of modulo. This length is 384 here, thus
- * we effectiviely doing a mod(384)
- */
- if (msb > 0) {
- BigNum tmp;
- bnBegin(&tmp);
- bnSetQ (&tmp, 1);
- bnLShift (&tmp, maxMsb);
- bnMod(r, r, &tmp);
- bnEnd(&tmp);
- }
- }
- else {
- *(A(12)) = 0;
- bnInsertBigBytes(r, A(12), 0, 49); /* 49: 12 * 4 byte words + 1 carry byte */
- }
- while (bnCmp(r, modulo) >= 0) {
- bnSub(r, modulo);
- }
- return 0;
-}
-#undef A
-
-
-/* new modulo for 521bit curve, much easier because the prime for 521 is a real Mersenne prime */
-static int newMod521(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
- unsigned char buf1[200] = {0};
- unsigned char buf2[200] = {0};
- unsigned char *p1;
- unsigned char *p2;
- size_t modSize;
- short ac = 0;
- unsigned int i;
- int cmp;
-
- /* TODO: check if a is > modulo^2 */
-#if 0
- if (a->s < 0) /* is it a negative value? */
- return bnMod(r, a, modulo);
-#endif
- cmp = bnCmp(modulo, a);
- if (cmp == 0) { /* a is equal modulo, set resul to zero */
- bnSetQ(r, 0);
- return 0;
- }
- bnCopy(r, a);
- if (cmp > 0) { /* modulo is greater than a - return the prepared r */
- return 0;
- }
- modSize = bnBytes(modulo);
-
- bnExtractBigBytes(a, buf1, 0, modSize*2); /* a must be less modulo^2 */
- buf1[modSize] &= 1; /* clear all bits except least significat */
-
- bnRShift(r, 521);
- bnExtractBigBytes(r, buf2, 0, modSize*2);
- buf2[modSize] &= 1;
-
- p1 = &buf2[131]; /* p1 is pointer to A0 */
- p2 = &buf1[131]; /* p2 is pointer to A1 */
-
- for (i = 0; i < modSize; i++) {
- ac += *p1 + *p2--; *p1-- = ac; ac >>= 8;
- }
- bnSetQ(r, 0);
- bnInsertBigBytes(r, p1+1, 0, modSize);
-
- while (bnCmp(r, modulo) >= 0) {
- bnSub(r, modulo);
- }
- return 0;
-}
-
diff --git a/jni/libzrtp/sources/bnlib/ec/ec.h b/jni/libzrtp/sources/bnlib/ec/ec.h
deleted file mode 100644
index 172ffd8..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ec.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#ifndef _EC_H_
-#define _EC_H_
-
-#include <bn.h>
-
-/**
- * @file ec.h
- * @brief Elliptic curve functions for bnlib
- * @defgroup BNLIB_EC Elliptic curve functions
- * @{
- */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct BigNum BigNum;
-
-typedef enum {
- NIST192P = 1,
- NIST224P = 2,
- NIST256P = 3,
- NIST384P = 4,
- NIST521P = 5,
- Curve25519 = 10,
- Curve3617 = 11
-} Curves;
-
-/**
- * \brief This structure contains the x, y affine coordinates and the z value if we
- * use projective coordinates during EC point arithmetic.
- */
-typedef struct _EcPoint {
- BigNum *x, *y, *z;
- BigNum tx, ty, tz;
-} EcPoint;
-
-/**
- * @brief This structure contains the value of EC curves over Prime Fields.
- *
- * The for NIST curves the field names correspond to the variable names defined in
- * NIST FIPS 186-3, E.1.2. The <b>a</b> curve parameter is the constant -3 and is
- * computed during initialization of the curve structure.
- *
- * For other curves, for example curve3917 we have less parameters to fill in, mostly
- * the prime number, the base point, etc. Refer to the curve's initialization function
- * about the use of the fileds.
- */
-struct EcCurve;
-struct EcCurve {
- Curves id;
- BigNum _p;
- BigNum _n;
- BigNum _SEED;
- BigNum _c;
- BigNum _a;
- BigNum _b;
- BigNum _Gx;
- BigNum _Gy;
- /* Pointers to the BigNum structures, for better readability mainly */
- BigNum *p;
- BigNum *n;
- BigNum *SEED;
- BigNum *c;
- BigNum *a;
- BigNum *b;
- BigNum *Gx;
- BigNum *Gy;
- /* some scratch pad variables, the EC algorithms use them to
- avoid to much memory allocation/deallocatio0n overhead */
- BigNum _S1, _U1, _H, _R, _t0, _t1, _t2, _t3;
- BigNum *S1, *U1, *H, *R, *t0, *t1, *t2, *t3;
- int (*affineOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
- int (*doubleOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
- int (*addOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
- int (*modOp)(BigNum *, const BigNum *, const BigNum *);
- int (*checkPubOp)(const struct EcCurve *curve, const EcPoint *pub);
- int (*randomOp)(const struct EcCurve *curve, BigNum *d);
- int (*mulScalar)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-};
-
-typedef struct EcCurve EcCurve;
-typedef EcCurve NistECpCurve;
-
-/**
- * \brief Marco to initialize a EC point structure.
- *
- * \param P Address of the EC point structure
- */
-#define INIT_EC_POINT(P) {EcPoint *e = P; e->x = &e->tx; e->y = &e->ty; e->z = &e->tz; bnBegin(e->x); bnBegin(e->y); bnBegin(e->z);}
-
-/**
- * \brief Marco to free a EC point structure.
- *
- * \param P Address of the EC point structure
- */
-#define FREE_EC_POINT(P) {EcPoint *e = P; bnEnd(e->x); bnEnd(e->y); bnEnd(e->z);}
-
-/**
- * \brief Marco to set a EC point structure to the curve's base point.
- *
- * \param C Address of the NistECpCurve structure.
- *
- * \param P Address of the EC point structure.
- */
-#define SET_EC_BASE_POINT(C, P) {EcPoint *e = P; const EcCurve *c = C; bnCopy(e->x, c->Gx); bnCopy(e->y, c->Gy); bnSetQ(e->z, 1);}
-
-/*
- * EC point helper functions
- */
-extern void ecInitPoint(EcPoint *P);
-
-extern void ecFreePoint(EcPoint *P);
-
-extern void ecSetBasePoint(EcCurve *C, EcPoint *P);
-
-/**
- * \brief Get NIST EC curve parameters.
- *
- * Before reusing a EC curve structure make sure to call ecFreeCurveNistECp
- * to return memory.
- *
- * \param curveId Which curve to initialize
- *
- * \param curve Pointer to a EcCurve structure
- *
- * \return 0 if successful
- *
- * \note Call ecFreeCurveNistECp to return allocated memory.
- */
-int ecGetCurveNistECp(Curves curveId, NistECpCurve *curve);
-
-
-/**
- * \brief Free EC curve parameters.
- *
- * \param curve Pointer to a EcCurve structure
- *
- * \note Curve parameters must be initialized calling ecGetCurveNistECp.
- */
-void ecFreeCurveNistECp(EcCurve *curve);
-
-/**
- * \brief Double an EC point.
- *
- * This function uses affine coordinates to perform the computations. For
- * further reference see RFC 6090 or the standard work <i>Guide to Elliptic
- * Curve Cryptography</i>.
- *
- * \param curve Address of EC curve structure
- * \param R Address of resulting EC point structure
- * \param P Address of the EC point structure
- *
- * \return 0 if successful
- */
-int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-/**
- * \brief Add two EC points.
- *
- * This function uses affine coordinates to perform the computations. For
- * further reference see RFC 6090 or the standard work <i>Guide to Elliptic
- * Curve Cryptography</i>.
- *
- * \param curve Address of EC curve structure
- * \param R Address of resulting EC point structure
- * \param P Address of the first EC point structure
- * \param Q Address of the second EC point structure
- *
- * \return 0 if successful
- */
-int ecAddPoint(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-
-/**
- * \brief Mulitply an EC point with a scalar value.
- *
- * \param curve Address of EC curve structure
- * \param R Address of resulting EC point structure
- * \param P Address of the EC point structure
- * \param scalar Address of the scalar multi-precision integer value
- *
- * \return 0 if successful
- */
-int ecMulPointScalar(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-/**
- * \brief Convert an EC point from Jacobian projective coordinates to normal affine x/y coordinates.
- *
- * \param curve Address of EC curve structure
- * \param R Address of EC point structure that receives the x/y coordinates
- * \param P Address of the EC point structure that contains the jacobian x/y/z coordinates.
- *
- * \return 0 if successful
- */
-int ecGetAffine(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-/**
- * @brief Generate a random number.
- *
- * The method generates a random number and checks if it matches the curve restricitions.
- * Use this number as ECDH private key.
- *
- * @param curve the NIST curve to use.
- *
- * @param d receives the generated random number.
- */
-int ecGenerateRandomNumber(const NistECpCurve *curve, BigNum *d);
-
-/**
- * @brief Check a public key.
- *
- * The method checks if a public key is valid. For NIST curves it uses the
- * ECC Partial Validation, NIST SP800-56A section 5.6.2.6
- *
- * For other curves it computes the equation and compares the left hand and
- * the right handresults. If they are equal the point is on the curve.
- *
- * @param curve the curve to use.
- *
- * @param pub the public key to check.
- *
- * @returns true (!0) if the check was ok, false (0) otherwise.
- *
- * @note The function uses some scratch pad variable of the NistECpCurve structure.
- */
-int ecCheckPubKey(const EcCurve *curve, const EcPoint *pub);
-
-int ecGetCurvesCurve(Curves curveId, EcCurve *curve);
-
-void ecFreeCurvesCurve(EcCurve *curve);
-
-/**
- * This is a special function for DJB's curve 25519. Actually it's the scalar multiplication
- * mypublic = basepoint * secret
- */
-int curve25519_donna(unsigned char *mypublic, const unsigned char *secret, const unsigned char *basepoint);
-
-/*
- * Some additional functions that are not available in bnlib
- */
-int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
-
-int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
-
-int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
-
-int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
-
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve);
-
-int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve);
-
-int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * @}
- */
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.c b/jni/libzrtp/sources/bnlib/ec/ecdh.c
deleted file mode 100644
index 8d1bc23..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-
-#include <ec/ec.h>
-#include <ec/ecdh.h>
-
-int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d)
-{
- EcPoint G;
-
- INIT_EC_POINT(&G);
- SET_EC_BASE_POINT(curve, &G);
-
- ecMulPointScalar(curve, Q, &G, d);
- ecGetAffine(curve, Q, Q);
-
- FREE_EC_POINT(&G);
-
- return ecCheckPubKey(curve, Q);
-}
-
-int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d)
-{
- EcPoint t0;
-
- INIT_EC_POINT(&t0);
-
- ecMulPointScalar(curve, &t0, Q, d);
- ecGetAffine(curve, &t0, &t0);
- /* TODO: check for infinity here */
-
- bnCopy(agreement, t0.x);
-
- FREE_EC_POINT(&t0);
-
- return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.h b/jni/libzrtp/sources/bnlib/ec/ecdh.h
deleted file mode 100644
index 7ec32ad..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#ifndef _ECDH_H_
-#define _ECDH_H_
-/**
- * @file ec.h
- * @brief Elliptic Diffie-Hellman functions for bnlib
- * @defgroup BNLIB_EC Elliptic curve functions
- * @{
- */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief Takes a secret large random number and computes the public EC point.
- *
- * @param curve is the curve to use.
- *
- * @param Q the functions writes the computed public point in this parameter.
- *
- * @param d is the secret random number.
- *
- * @return @c true (!0) if public key was computed, @c false otherwise.
- *
- * @sa ecGenerateRandomNumber
- */
-int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d);
-
-/**
- * @brief Computes the key agreement value.
- *
- * Takes the public EC point of the other party and applies the EC DH algorithm
- * to compute the agreed value.
- *
- * @param curve is the curve to use, must be the same curve as used in
- * @c ecdhGeneratePublic.
- *
- * @param agreemtn the functions writes the computed agreed value in this parameter.
- *
- * @param Q is the other party's public point.
- *
- * @param d is the secret random number.
- */
-int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d);
-
-#ifdef __cplusplus
-}
-#endif
-/**
- * @}
- */
-
-#endif
\ No newline at end of file
diff --git a/jni/libzrtp/sources/bnlib/germain.c b/jni/libzrtp/sources/bnlib/germain.c
deleted file mode 100644
index 52dbb50..0000000
--- a/jni/libzrtp/sources/bnlib/germain.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Sophie Germain prime generation using the bignum library and sieving.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include "bnconfig.h"
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#define BNDEBUG 1
-#ifndef BNDEBUG
-#define BNDEBUG 0
-#endif
-#if BNDEBUG
-#include <stdio.h>
-#endif
-
-#include "bn.h"
-#include "germain.h"
-#include "jacobi.h"
-#include "lbnmem.h" /* For lbnMemWipe */
-#include "sieve.h"
-
-#include "kludge.h"
-
-/* Size of the sieve area (can be up to 65536/8 = 8192) */
-#define SIEVE 8192
-
-static unsigned const confirm[] = {2, 3, 5, 7, 11, 13, 17};
-#define CONFIRMTESTS (sizeof(confirm)/sizeof(*confirm))
-
-#if BNDEBUG
-/*
- * For sanity checking the sieve, we check for small divisors of the numbers
- * we get back. This takes "rem", a partially reduced form of the prime,
- * "div" a divisor to check for, and "order", a parameter of the "order"
- * of Sophie Germain primes (0 = normal primes, 1 = Sophie Germain primes,
- * 2 = 4*p+3 is also prime, etc.) and does the check. It just complains
- * to stdout if the check fails.
- */
-static void
-germainSanity(unsigned rem, unsigned div, unsigned order)
-{
- unsigned mul = 1;
-
- rem %= div;
- if (!rem)
- printf("bn div by %u!\n", div);
- while (order--) {
- rem += rem+1;
- if (rem >= div)
- rem -= div;
- mul += mul;
- if (!rem)
- printf("%u*bn+%u div by %u!\n", mul, mul-1, div);
- }
-}
-#endif /* BNDEBUG */
-
-/*
- * Helper function that does the slow primality test.
- * bn is the input bignum; a, e and bn2 are temporary buffers that are
- * allocated by the caller to save overhead. bn2 is filled with
- * a copy of 2^order*bn+2^order-1 if bn is found to be prime.
- *
- * Returns 0 if both bn and bn2 are prime, >0 if not prime, and -1 on
- * error (out of memory). If not prime, the return value is the number
- * of modular exponentiations performed. Prints a '+' or '-' on the
- * given FILE (if any) for each test that is passed by bn, and a '*'
- * for each test that is passed by bn2.
- *
- * The testing consists of strong pseudoprimality tests, to the bases given
- * in the confirm[] array above. (Also called Miller-Rabin, although that's
- * not technically correct if we're using fixed bases.) Some people worry
- * that this might not be enough. Number theorists may wish to generate
- * primality proofs, but for random inputs, this returns non-primes with
- * a probability which is quite negligible, which is good enough.
- *
- * It has been proved (see Carl Pomerance, "On the Distribution of
- * Pseudoprimes", Math. Comp. v.37 (1981) pp. 587-593) that the number of
- * pseudoprimes (composite numbers that pass a Fermat test to the base 2)
- * less than x is bounded by:
- * exp(ln(x)^(5/14)) <= P_2(x) ### CHECK THIS FORMULA - it looks wrong! ###
- * P_2(x) <= x * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))).
- * Thus, the local density of Pseudoprimes near x is at most
- * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))), and at least
- * exp(ln(x)^(5/14) - ln(x)). Here are some values of this function
- * for various k-bit numbers x = 2^k:
- * Bits Density <= Bit equivalent Density >= Bit equivalent
- * 128 3.577869e-07 21.414396 4.202213e-37 120.840190
- * 192 4.175629e-10 31.157288 4.936250e-56 183.724558
- * 256 5.804314e-13 40.647940 4.977813e-75 246.829095
- * 384 1.578039e-18 59.136573 3.938861e-113 373.400096
- * 512 5.858255e-24 77.175803 2.563353e-151 500.253110
- * 768 1.489276e-34 112.370944 7.872825e-228 754.422724
- * 1024 6.633188e-45 146.757062 1.882404e-304 1008.953565
- *
- * As you can see, there's quite a bit of slop between these estimates.
- * In fact, the density of pseudoprimes is conjectured to be closer to the
- * square of that upper bound. E.g. the density of pseudoprimes of size
- * 256 is around 3 * 10^-27. The density of primes is very high, from
- * 0.005636 at 256 bits to 0.001409 at 1024 bits, i.e. more than 10^-3.
- *
- * For those people used to cryptographic levels of security where the
- * 56 bits of DES key space is too small because it's exhaustible with
- * custom hardware searching engines, note that you are not generating
- * 50,000,000 primes per second on each of 56,000 custom hardware chips
- * for several hours. The chances that another Dinosaur Killer asteroid
- * will land today is about 10^-11 or 2^-36, so it would be better to
- * spend your time worrying about *that*. Well, okay, there should be
- * some derating for the chance that astronomers haven't seen it yet,
- * but I think you get the idea. For a good feel about the probability
- * of various events, I have heard that a good book is by E'mile Borel,
- * "Les Probabilite's et la vie". (The 's are accents, not apostrophes.)
- *
- * For more on the subject, try "Finding Four Million Large Random Primes",
- * by Ronald Rivest, in Advancess in Cryptology: Proceedings of Crypto
- * '90. He used a small-divisor test, then a Fermat test to the base 2,
- * and then 8 iterations of a Miller-Rabin test. About 718 million random
- * 256-bit integers were generated, 43,741,404 passed the small divisor
- * test, 4,058,000 passed the Fermat test, and all 4,058,000 passed all
- * 8 iterations of the Miller-Rabin test, proving their primality beyond
- * most reasonable doubts.
- *
- * If the probability of getting a pseudoprime is some small p, then the
- * probability of not getting it in t trials is (1-p)^t. Remember that,
- * for small p, (1-p)^(1/p) ~ 1/e, the base of natural logarithms.
- * (This is more commonly expressed as e = lim_{x\to\infty} (1+1/x)^x.)
- * Thus, (1-p)^t ~ e^(-p*t) = exp(-p*t). So the odds of being able to
- * do this many tests without seeing a pseudoprime if you assume that
- * p = 10^-6 (one in a million) is one in 57.86. If you assume that
- * p = 2*10^-6, it's one in 3347.6. So it's implausible that the density
- * of pseudoprimes is much more than one millionth the density of primes.
- *
- * He also gives a theoretical argument that the chance of finding a
- * 256-bit non-prime which satisfies one Fermat test to the base 2 is
- * less than 10^-22. The small divisor test improves this number, and
- * if the numbers are 512 bits (as needed for a 1024-bit key) the odds
- * of failure shrink to about 10^-44. Thus, he concludes, for practical
- * purposes *one* Fermat test to the base 2 is sufficient.
- */
-static int
-germainPrimeTest(struct BigNum const *bn, struct BigNum *bn2, struct BigNum *e,
- struct BigNum *a, unsigned order, int (*f)(void *arg, int c), void *arg)
-{
- int err;
- unsigned i;
- int j;
- unsigned k, l, n;
-
-#if BNDEBUG /* Debugging */
- /*
- * This is debugging code to test the sieving stage.
- * If the sieving is wrong, it will let past numbers with
- * small divisors. The prime test here will still work, and
- * weed them out, but you'll be doing a lot more slow tests,
- * and presumably excluding from consideration some other numbers
- * which might be prime. This check just verifies that none
- * of the candidates have any small divisors. If this
- * code is enabled and never triggers, you can feel quite
- * confident that the sieving is doing its job.
- */
- i = bnLSWord(bn);
- if (!(i % 2)) printf("bn div by 2!");
- i = bnModQ(bn, 51051); /* 51051 = 3 * 7 * 11 * 13 * 17 */
- germainSanity(i, 3, order);
- germainSanity(i, 7, order);
- germainSanity(i, 11, order);
- germainSanity(i, 13, order);
- germainSanity(i, 17, order);
- i = bnModQ(bn, 63365); /* 63365 = 5 * 19 * 23 * 29 */
- germainSanity(i, 5, order);
- germainSanity(i, 19, order);
- germainSanity(i, 23, order);
- germainSanity(i, 29, order);
- i = bnModQ(bn, 47027); /* 47027 = 31 * 37 * 41 */
- germainSanity(i, 31, order);
- germainSanity(i, 37, order);
- germainSanity(i, 41, order);
-#endif
- /*
- * First, check whether bn is prime. This uses a fast primality
- * test which usually obviates the need to do one of the
- * confirmation tests later. See prime.c for a full explanation.
- * We check bn first because it's one bit smaller, saving one
- * modular squaring, and because we might be able to save another
- * when testing it. (1/4 of the time.) A small speed hack,
- * but finding big Sophie Germain primes is *slow*.
- */
- if (bnCopy(e, bn) < 0)
- return -1;
- (void)bnSubQ(e, 1);
- l = bnLSWord(e);
-
- j = 1; /* Where to start in prime array for strong prime tests */
-
- if (l & 7) {
- bnRShift(e, 1);
- if (bnTwoExpMod(a, e, bn) < 0)
- return -1;
- if ((l & 7) == 6) {
- /* bn == 7 mod 8, expect +1 */
- if (bnBits(a) != 1)
- return 1; /* Not prime */
- k = 1;
- } else {
- /* bn == 3 or 5 mod 8, expect -1 == bn-1 */
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) != 0)
- return 1; /* Not prime */
- k = 1;
- if (l & 4) {
- /* bn == 5 mod 8, make odd for strong tests */
- bnRShift(e, 1);
- k = 2;
- }
- }
- } else {
- /* bn == 1 mod 8, expect 2^((bn-1)/4) == +/-1 mod bn */
- bnRShift(e, 2);
- if (bnTwoExpMod(a, e, bn) < 0)
- return -1;
- if (bnBits(a) == 1) {
- j = 0; /* Re-do strong prime test to base 2 */
- } else {
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) != 0)
- return 1; /* Not prime */
- }
- k = 2 + bnMakeOdd(e);
- }
-
-
- /*
- * It's prime! Now check higher-order forms bn2 = 2*bn+1, 4*bn+3,
- * etc. Since bn2 == 3 mod 4, a strong pseudoprimality test boils
- * down to looking at a^((bn2-1)/2) mod bn and seeing if it's +/-1.
- * (+1 if bn2 is == 7 mod 8, -1 if it's == 3)
- * Of course, that exponent is just the previous bn2 or bn...
- */
- if (bnCopy(bn2, bn) < 0)
- return -1;
- for (n = 0; n < order; n++) {
- /*
- * Print a success indicator: the sign of Jacobi(2,bn2),
- * which is available to us in l. bn2 = 2*bn + 1. Since bn
- * is odd, bn2 must be == 3 mod 4, so the options modulo 8
- * are 3 and 7. 3 if l == 1 mod 4, 7 if l == 3 mod 4.
- * The sign of the Jacobi symbol is - and + for these cases,
- * respectively.
- */
- if (f && (err = f(arg, "-+"[(l >> 1) & 1])) < 0)
- return err;
- /* Exponent is previous bn2 */
- if (bnCopy(e, bn2) < 0 || bnLShift(bn2, 1) < 0)
- return -1;
- (void)bnAddQ(bn2, 1); /* Can't overflow */
- if (bnTwoExpMod(a, e, bn2) < 0)
- return -1;
- if (n | l) { /* Expect + */
- if (bnBits(a) != 1)
- return 2+n; /* Not prime */
- } else {
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn2) != 0)
- return 2+n; /* Not prime */
- }
- l = bnLSWord(bn2);
- }
-
- /* Final success indicator - it's in the bag. */
- if (f && (err = f(arg, '*')) < 0)
- return err;
-
- /*
- * Success! We have found a prime! Now go on to confirmation
- * tests... k is an amount by which we know it's safe to shift
- * down e. j = 1 unless the test to the base 2 could stand to be
- * re-done (it wasn't *quite* a strong test), in which case it's 0.
- *
- * Here, we do the full strong pseudoprimality test. This proves
- * that a number is composite, or says that it's probably prime.
- *
- * For the given base a, find bn-1 = 2^k * e, then find
- * x == a^e (mod bn).
- * If x == +1 -> strong pseudoprime to base a
- * Otherwise, repeat k times:
- * If x == -1, -> strong pseudoprime
- * x = x^2 (mod bn)
- * If x = +1 -> composite
- * If we reach the end of the iteration and x is *not* +1, at the
- * end, it is composite. But it's also composite if the result
- * *is* +1. Which means that the squaring actually only has to
- * proceed k-1 times. If x is not -1 by then, it's composite
- * no matter what the result of the squaring is.
- *
- * For the multiples 2*bn+1, 4*bn+3, etc. then k = 1 (and e is
- * the previous multiple of bn) so the squaring loop is never
- * actually executed at all.
- */
- for (i = j; i < CONFIRMTESTS; i++) {
- if (bnCopy(e, bn) < 0)
- return -1;
- bnRShift(e, k);
- k += bnMakeOdd(e);
- (void)bnSetQ(a, confirm[i]);
- if (bnExpMod(a, a, e, bn) < 0)
- return -1;
-
- if (bnBits(a) != 1) {
- l = k;
- for (;;) {
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) == 0) /* Was result bn-1? */
- break; /* Prime */
- if (!--l)
- return (1+order)*i+2; /* Fail */
- /* This part is executed once, on average. */
- (void)bnSubQ(a, 1); /* Restore a */
- if (bnSquare(a, a) < 0 || bnMod(a, a, bn) < 0)
- return -1;
- if (bnBits(a) == 1)
- return (1+order)*i+1; /* Fail */
- }
- }
-
- if (bnCopy(bn2, bn) < 0)
- return -1;
-
- /* Only do the following if we're not re-doing base 2 */
- if (i) for (n = 0; n < order; n++) {
- if (bnCopy(e, bn2) < 0 || bnLShift(bn2, 1) < 0)
- return -1;
- (void)bnAddQ(bn2, 1);
-
- /* Print success indicator for previous test */
- j = bnJacobiQ(confirm[i], bn2);
- if (f && (err = f(arg, j < 0 ? '-' : '+')) < 0)
- return err;
-
- /* Check that p^e == Jacobi(p,bn2) (mod bn2) */
- (void)bnSetQ(a, confirm[i]);
- if (bnExpMod(a, a, e, bn2) < 0)
- return -1;
- /*
- * FIXME: Actually, we don't need to compute the
- * Jacobi symbol externally... it never happens that
- * a = +/-1 but it's the wrong one. So we can just
- * look at a and use its sign. Find a proof somewhere.
- */
- if (j < 0) {
- /* Not a Q.R., should have a = bn2-1 */
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn2) != 0) /* Was result bn2-1? */
- return (1+order)*i+n+2; /* Fail */
- } else {
- /* Quadratic residue, should have a = 1 */
- if (bnBits(a) != 1)
- return (1+order)*i+n+2; /* Fail */
- }
- }
- /* Final success indicator for the base confirm[i]. */
- if (f && (err = f(arg, '*')) < 0)
- return err;
- }
-
- return 0; /* Prime! */
-}
-
-/*
- * Add x*y to bn, which is usually (but not always) < 65536.
- * Do it in a simple linear manner.
- */
-static int
-bnAddMult(struct BigNum *bn, unsigned long x, unsigned y)
-{
- unsigned long z = (unsigned long)x * y;
-
- while (z > 65535) {
- if (bnAddQ(bn, 65535) < 0)
- return -1;
- z -= 65535;
- }
- return bnAddQ(bn, (unsigned)z);
-}
-
-/*
- * Modifies the bignum to return the next Sophie Germain prime >= the
- * input value. Sohpie Germain primes are number such that p is
- * prime and 2*p+1 is also prime.
- *
- * This is actually parameterized: it generates primes p such that "order"
- * multiples-plus-two are also prime, 2*p+1, 2*(2*p+1)+1 = 4*p+3, etc.
- *
- * Returns >=0 on success or -1 on failure (out of memory). On success,
- * the return value is the number of modular exponentiations performed
- * (excluding the final confirmations). This never gives up searching.
- *
- * The FILE *f argument, if non-NULL, has progress indicators written
- * to it. A dot (.) is written every time a primeality test is failed,
- * a plus (+) or minus (-) when the smaller prime of the pair passes a
- * test, and a star (*) when the larger one does. Finally, a slash (/)
- * is printed when the sieve was emptied without finding a prime and is
- * being refilled.
- *
- * Apologies to structured programmers for all the GOTOs.
- */
-int
-germainPrimeGen(struct BigNum *bn, unsigned order,
- int (*f)(void *arg, int c), void *arg)
-{
- int retval;
- unsigned p, prev;
- unsigned inc;
- struct BigNum a, e, bn2;
- int modexps = 0;
-#ifdef MSDOS
- unsigned char *sieve;
-#else
- unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
- sieve = lbnMemAlloc(SIEVE);
- if (!sieve)
- return -1;
-#endif
-
- bnBegin(&a);
- bnBegin(&e);
- bnBegin(&bn2);
-
- /*
- * Obviously, the prime we find must be odd. Further, if 2*p+1
- * is also to be prime (order > 0) then p != 1 (mod 3), lest
- * 2*p+1 == 3 (mod 3). Added to p != 3 (mod 3), p == 2 (mod 3)
- * and p == 5 (mod 6).
- * If order > 2 and we care about 4*p+3 and 8*p+7, then similarly
- * p == 4 (mod 5), so p == 29 (mod 30).
- * So pick the step size for searching based on the order
- * and increse bn until it's == -1 (mod inc).
- *
- * mod 7 doesn't have a unique value for p because 2 -> 5 -> 4 -> 2,
- * nor does mod 11, and I don't want to think about things past
- * that. The required order would be impractically high, in any case.
- */
- inc = order ? ((order > 2) ? 30 : 6) : 2;
- if (bnAddQ(bn, inc-1 - bnModQ(bn, inc)) < 0)
- goto failed;
-
- for (;;) {
- if (sieveBuild(sieve, SIEVE, bn, inc, order) < 0)
- goto failed;
-
- p = prev = 0;
- if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
- do {
- /* Adjust bn to have the right value. */
- assert(p >= prev);
- if (bnAddMult(bn, p-prev, inc) < 0)
- goto failed;
- prev = p;
-
- /* Okay, do the strong tests. */
- retval = germainPrimeTest(bn, &bn2, &e, &a,
- order, f, arg);
- if (retval <= 0)
- goto done;
- modexps += retval;
- if (f && (retval = f(arg, '.')) < 0)
- goto done;
-
- /* And try again */
- p = sieveSearch(sieve, SIEVE, p);
- } while (p);
- }
-
- /* Ran out of sieve space - increase bn and keep trying. */
- if (bnAddMult(bn, (unsigned long)SIEVE*8-prev, inc) < 0)
- goto failed;
- if (f && (retval = f(arg, '/')) < 0)
- goto done;
- } /* for (;;) */
-
-failed:
- retval = -1;
-done:
- bnEnd(&bn2);
- bnEnd(&e);
- bnEnd(&a);
-#ifdef MSDOS
- lbnMemFree(sieve, SIEVE);
-#else
- lbnMemWipe(sieve, sizeof(sieve));
-#endif
- return retval < 0 ? retval : modexps+(order+1)*CONFIRMTESTS;
-}
-
-int
-germainPrimeGenStrong(struct BigNum *bn, struct BigNum const *step,
- unsigned order, int (*f)(void *arg, int c), void *arg)
-{
- int retval;
- unsigned p, prev;
- struct BigNum a, e, bn2;
- int modexps = 0;
-#ifdef MSDOS
- unsigned char *sieve;
-#else
- unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
- sieve = lbnMemAlloc(SIEVE);
- if (!sieve)
- return -1;
-#endif
- bnBegin(&a);
- bnBegin(&e);
- bnBegin(&bn2);
-
- for (;;) {
- if (sieveBuildBig(sieve, SIEVE, bn, step, order) < 0)
- goto failed;
-
- p = prev = 0;
- if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
- do {
- /*
- * Adjust bn to have the right value,
- * adding (p-prev) * 2*step.
- */
- assert(p >= prev);
- /* Compute delta into a */
- if (bnMulQ(&a, step, p-prev) < 0)
- goto failed;
- if (bnAdd(bn, &a) < 0)
- goto failed;
- prev = p;
-
- /* Okay, do the strong tests. */
- retval = germainPrimeTest(bn, &bn2, &e, &a,
- order, f, arg);
- if (retval <= 0)
- goto done;
- modexps += retval;
- if (f && (retval = f(arg, '.')) < 0)
- goto done;
-
- /* And try again */
- p = sieveSearch(sieve, SIEVE, p);
- } while (p);
- }
-
- /* Ran out of sieve space - increase bn and keep trying. */
-#if SIEVE*8 == 65536
- /* Corner case that will never actually happen */
- if (!prev) {
- if (bnAdd(bn, step) < 0)
- goto failed;
- p = 65535;
- } else {
- p = (unsigned)(SIEVE*8 - prev);
- }
-#else
- p = SIEVE*8 - prev;
-#endif
- if (bnMulQ(&a, step, p) < 0 || bnAdd(bn, &a) < 0)
- goto failed;
- if (f && (retval = f(arg, '/')) < 0)
- goto done;
- } /* for (;;) */
-
-failed:
- retval = -1;
-done:
- bnEnd(&bn2);
- bnEnd(&e);
- bnEnd(&a);
-#ifdef MSDOS
- lbnMemFree(sieve, SIEVE);
-#else
- lbnMemWipe(sieve, sizeof(sieve));
-#endif
- return retval < 0 ? retval : modexps+(order+1)*CONFIRMTESTS;
-}
diff --git a/jni/libzrtp/sources/bnlib/germain.h b/jni/libzrtp/sources/bnlib/germain.h
deleted file mode 100644
index f1e018a..0000000
--- a/jni/libzrtp/sources/bnlib/germain.h
+++ /dev/null
@@ -1,8 +0,0 @@
-struct BigNum;
-
-/* Generate a Sophie Germain prime */
-int germainPrimeGen(struct BigNum *bn, unsigned order,
- int (*f)(void *arg, int c), void *arg);
-/* The same, but search for using the given step size */
-int germainPrimeGenStrong(struct BigNum *bn, struct BigNum const *step,
- unsigned order, int (*f)(void *arg, int c), void *arg);
diff --git a/jni/libzrtp/sources/bnlib/jacobi.c b/jni/libzrtp/sources/bnlib/jacobi.c
deleted file mode 100644
index 24b7313..0000000
--- a/jni/libzrtp/sources/bnlib/jacobi.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Compute the Jacobi symbol (small prime case only).
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#include "bn.h"
-#include "jacobi.h"
-
-/*
- * For a small (usually prime, but not necessarily) prime p,
- * compute Jacobi(p,bn), which is -1, 0 or +1, using the following rules:
- * Jacobi(x, y) = Jacobi(x mod y, y)
- * Jacobi(0, y) = 0
- * Jacobi(1, y) = 1
- * Jacobi(2, y) = 0 if y is even, +1 if y is +/-1 mod 8, -1 if y = +/-3 mod 8
- * Jacobi(x1*x2, y) = Jacobi(x1, y) * Jacobi(x2, y) (used with x1 = 2 & x1 = 4)
- * If x and y are both odd, then
- * Jacobi(x, y) = Jacobi(y, x) * (-1 if x = y = 3 mod 4, +1 otherwise)
- */
-int
-bnJacobiQ(unsigned p, struct BigNum const *bn)
-{
- int j = 1;
- unsigned u = bnLSWord(bn);
-
- if (!(u & 1))
- return 0; /* Don't *do* that */
-
- /* First, get rid of factors of 2 in p */
- while ((p & 3) == 0)
- p >>= 2;
- if ((p & 1) == 0) {
- p >>= 1;
- if ((u ^ u>>1) & 2)
- j = -j; /* 3 (011) or 5 (101) mod 8 */
- }
- if (p == 1)
- return j;
- /* Then, apply quadratic reciprocity */
- if (p & u & 2) /* p = u = 3 (mod 4? */
- j = -j;
- /* And reduce u mod p */
- u = bnModQ(bn, p);
-
- /* Now compute Jacobi(u,p), u < p */
- while (u) {
- while ((u & 3) == 0)
- u >>= 2;
- if ((u & 1) == 0) {
- u >>= 1;
- if ((p ^ p>>1) & 2)
- j = -j; /* 3 (011) or 5 (101) mod 8 */
- }
- if (u == 1)
- return j;
- /* Now both u and p are odd, so use quadratic reciprocity */
- if (u < p) {
- unsigned t = u; u = p; p = t;
- if (u & p & 2) /* u = p = 3 (mod 4? */
- j = -j;
- }
- /* Now u >= p, so it can be reduced */
- u %= p;
- }
- return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/jacobi.h b/jni/libzrtp/sources/bnlib/jacobi.h
deleted file mode 100644
index 4dfd1e2..0000000
--- a/jni/libzrtp/sources/bnlib/jacobi.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * For a small (usually prime, but not necessarily) prime p,
- * Return Jacobi(p,bn), which is -1, 0 or +1.
- * bn must be odd.
- */
-struct BigNum;
-int bnJacobiQ(unsigned p, struct BigNum const *bn);
diff --git a/jni/libzrtp/sources/bnlib/kludge.h b/jni/libzrtp/sources/bnlib/kludge.h
deleted file mode 100644
index 023c890..0000000
--- a/jni/libzrtp/sources/bnlib/kludge.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef KLUDGE_H
-#define KLUDGE_H
-
-/*
- * Kludges for not-quite-ANSI systems.
- * This should always be the last file included, because it may
- * mess up some system header files.
- */
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef ASSERT_NEEDS_STDIO
-#define ASSERT_NEEDS_STDIO 0
-#endif
-#ifndef ASSERT_NEEDS_STDLIB
-#define ASSERT_NEEDS_STDLIB 0
-#endif
-#ifndef NO_STDLIB_H
-#define NO_STDLIB_H 0
-#endif
-
-/* SunOS 4.1.x <assert.h> needs "stderr" defined, and "exit" declared... */
-#ifdef assert
-#if ASSERT_NEEDS_STDIO
-#include <stdio.h>
-#endif
-#if ASSERT_NEEDS_STDLIB
-#if !NO_STDLIB_H
-#include <stdlib.h>
-#endif
-#endif
-#endif
-
-#ifndef NO_MEMMOVE
-#define NO_MEMMOVE 0
-#endif
-#if NO_MEMMOVE /* memove() not in libraries */
-#define memmove(dest,src,len) bcopy(src,dest,len)
-#endif
-
-#ifndef NO_MEMCPY
-#define NO_MEMCPY 0
-#endif
-#if NO_MEMCPY /* memcpy() not in libraries */
-#define memcpy(dest,src,len) bcopy(src,dest,len)
-#endif
-
-#ifndef MEM_PROTOS_BROKEN
-#define MEM_PROTOS_BROKEN 0
-#endif
-#if MEM_PROTOS_BROKEN
-#define memcpy(d,s,l) memcpy((void *)(d), (void const *)(s), l)
-#define memmove(d,s,l) memmove((void *)(d), (void const *)(s), l)
-#define memcmp(d,s,l) memcmp((void const *)(d), (void const *)(s), l)
-#define memset(d,v,l) memset((void *)(d), v, l)
-#endif
-
-/*
- * If there are no prototypes for the stdio functions, use these to
- * reduce compiler warnings. Uses EOF as a giveaway to indicate
- * that <stdio.h> was #included.
- */
-#ifndef NO_STDIO_PROTOS
-#define NO_STDIO_PROTOS 0
-#endif
-#if NO_STDIO_PROTOS /* Missing prototypes for "simple" functions */
-#ifdef EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-int (puts)(char const *);
-int (fputs)(char const *, FILE *);
-int (fflush)(FILE *);
-int (printf)(char const *, ...);
-int (fprintf)(FILE *, char const *, ...);
-/* If we have a sufficiently old-fashioned stdio, it probably uses these... */
-int (_flsbuf)(int, FILE *);
-int (_filbuf)(FILE *);
-#ifdef __cplusplus
-}
-#endif
-#endif /* EOF */
-#endif /* NO_STDIO_PROTOS */
-
-/*
- * Borland C seems to think that it's a bad idea to decleare a
- * structure tag and not declare the contents. I happen to think
- * it's a *good* idea to use such "opaque" structures wherever
- * possible. So shut up.
- */
-#ifdef __BORLANDC__
-#pragma warn -stu
-#ifndef MSDOS
-#define MSDOS 1
-#endif
-#endif
-
-/* Turn off warning about negation of unsigned values */
-#ifdef _MSC_VER
-#pragma warning(disable:4146)
-#endif
-
-/* Cope with people forgetting to define the OS, if possible... */
-#ifndef MSDOS
-#ifdef __MSDOS
-#define MSDOS 1
-#endif
-#endif
-#ifndef MSDOS
-#ifdef __MSDOS__
-#define MSDOS 1
-#endif
-#endif
-
-/* By MS-DOS, we mean 16-bit brain-dead MS-DOS. Not GCC & GO32 */
-#ifdef __GO32
-#undef MSDOS
-#endif
-#ifdef __GO32__
-#undef MSDOS
-#endif
-
-#endif /* KLUDGE_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn.h b/jni/libzrtp/sources/bnlib/lbn.h
deleted file mode 100644
index 25f3784..0000000
--- a/jni/libzrtp/sources/bnlib/lbn.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * lbn.h - Low-level bignum header.
- * Defines various word sizes and useful macros.
- * TODO: Rewrite this to use <stdint.h> and/or <inttypes.h>
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef LBN_H
-#define LBN_H
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_LIMITS_H
-#define NO_LIMITS_H 0
-#endif
-
-#include <stdint.h> /* TODO: protect by configuration ifdef */
-
-/* Make sure we have 8-bit bytes */
-#if !NO_LIMITS_H
-#include <limits.h>
-#if UCHAR_MAX != 0xff || CHAR_BIT != 8
-#error The bignum library requires 8-bit unsigned characters.
-#endif
-#endif /* !NO_LIMITS_H */
-
-#ifdef BNINCLUDE /* If this is defined as, say, foo.h */
-#define STR(x) #x /* STR(BNINCLUDE) -> "BNINCLUDE" */
-#define XSTR(x) STR(x) /* XSTR(BNINCLUDE) -> STR(foo.h) -> "foo.h" */
-#include XSTR(BNINCLUDE) /* #include "foo.h" */
-#undef XSTR
-#undef STR
-#endif
-
-/* Do we want bnYield()? */
-#ifndef BNYIELD
-#define BNYIELD 0
-#endif
-
-/* Figure out the endianness */
-/* Error if more than one is defined */
-#if defined(BN_BIG_ENDIAN) && defined(BN_LITTLE_ENDIAN)
-#error Only one of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN may be defined
-#endif
-
-/*
- * If no preference is stated, little-endian C code is slightly more
- * efficient, so prefer that. (The endianness here does NOT have to
- * match the machine's native byte sex; the library's C code will work
- * either way. The flexibility is allowed for assembly routines
- * that do care.
- */
-#if !defined(BN_BIG_ENDIAN) && !defined(BN_LITTLE_ENDIAN)
-#define BN_LITTLE_ENDIAN 1
-#endif /* !BN_BIG_ENDIAN && !BN_LITTLE_ENDIAN */
-
-/* Macros to choose between big and little endian */
-#if defined(BN_BIG_ENDIAN)
-#define BIG(b) b
-#define LITTLE(l) /*nothing*/
-#define BIGLITTLE(b,l) b
-#elif BN_LITTLE_ENDIAN
-#define BIG(b) /*nothing*/
-#define LITTLE(l) l
-#define BIGLITTLE(b,l) l
-#else
-#error One of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN must be defined as 1
-#endif
-
-
-/*
- * Define a 16-bit unsigned type if available.
- * Unsigned short is preferred over unsigned int to make the type chosen
- * by this file more stable on platforms (such as many 68000 compilers)
- * which support both 16- and 32-bit ints.
- */
-#ifndef BNWORD16
-#if !defined USHRT_MAX || USHRT_MAX == 0xffff || UINT_MAX == 0xffff
-#define BNWORD16 uint16_t
-#endif
-#endif /* BNWORD16 */
-
-/*
- * Define a 32-bit unsigned type if available.
- * Unsigned long is preferred over unsigned int to make the type chosen
- * by this file more stable on platforms (such as many 68000 compilers)
- * which support both 16- and 32-bit ints.
- */
-#ifndef BNWORD32
-#if !defined ULONG_MAX || ULONG_MAX == 0xfffffffful || UINT_MAX == 0xffffffff || USHRT_MAX == 0xffffffff
-#define BNWORD32 uint32_t
-#endif
-#endif /* BNWORD32 */
-
-/*
- * Find a 64-bit unsigned type.
- * The conditions here are more complicated to avoid using numbers that
- * will choke lesser preprocessors (like 0xffffffffffffffff) unless
- * we're reasonably certain that they'll be acceptable.
- */
-#if !defined(BNWORD64) && ULONG_MAX > 0xffffffffUL
-#if ULONG_MAX == 0xffffffffffffffff
-#define BNWORD64 uint64_t
-#endif
-#endif
-
-/*
- * I would test the value of unsigned long long, but some *preprocessors*
- * don't constants that long even if the compiler can accept them, so it
- * doesn't work reliably. So cross our fingers and hope that it's a 64-bit
- * type.
- *
- * GCC uses ULONG_LONG_MAX. Solaris uses ULLONG_MAX. IRIX uses ULONGLONG_MAX.
- * Are there any other names for this?
- */
-#if !defined(BNWORD64) && \
- (defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX))
-#define BNWORD64 uint64_t
-#endif
-
-/* We don't even try to find a 128-bit type at the moment */
-
-#endif /* !LBN_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn00.c b/jni/libzrtp/sources/bnlib/lbn00.c
deleted file mode 100644
index 228ff07..0000000
--- a/jni/libzrtp/sources/bnlib/lbn00.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * lbn00.c - auto-size-detecting lbn??.c file.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bnsize00.h"
-
-#if BNSIZE64
-
-/* Include all of the C source file by reference */
-#include "lbn64.c"
-
-#elif BNSIZE32
-
-/* Include all of the C source file by reference */
-#include "lbn32.c"
-
-#else /* BNSIZE16 */
-
-/* Include all of the C source file by reference */
-#include "lbn16.c"
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/lbn16.c b/jni/libzrtp/sources/bnlib/lbn16.c
deleted file mode 100644
index 313094a..0000000
--- a/jni/libzrtp/sources/bnlib/lbn16.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn16.c - Low-level bignum routines, 16-bit version.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "16" and "32" appear in many places in this
- * file, including inside identifiers. Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly. Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions. Any reference to the number of bits
- * in a word must be the string "16", and that string must not appear
- * otherwise. Any reference to twice this number must appear as "32",
- * which likewise must not appear otherwise. Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (32)
- * first, then the smaller (16). When halving the bit size, do the
- * opposite. Otherwise, things will get wierd. Also, be sure to replace
- * every instance that appears. (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD16s. The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way. If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END. The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1]. This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative. The expression used in this
- * code, *(ptr-i) will, however, work. (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this. An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names. If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made. Use the BNINCLUDE file to do that. Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_16 lbnMulAdd1_16
- *
- * If you want to write asm routines, start with lbnMulAdd1_16().
- * This is the workhorse of modular exponentiation. lbnMulN1_16() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_16 if that has a custom version. lbnMulSub1_16 and
- * lbnDiv21_16 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_16 defined, writing the other two should
- * be pretty easy. (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_16 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD32)
- * type are lbnMulAdd1_16 and lbnMulSub1_16; if those are provided,
- * the rest follows. lbnDiv21_16, however, is a lot slower unless you
- * have them, and lbnModQ_16 takes after it. That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn16.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD16
-#error 16-bit bignum library requires a 16-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void); /* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach. One big advantage of this is that the assembly
- * support routines are simpler. The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach. This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster. Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default. Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries. I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words. <Marvin mode on> Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD16)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_16
-void
-lbnCopy_16(BNWORD16 *dest, BNWORD16 const *src, unsigned len)
-{
- memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
- len * sizeof(*src));
-}
-#endif /* !lbnCopy_16 */
-
-/*
- * Fill n words with zero. This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't. Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_16
-void
-lbnZero_16(BNWORD16 *num, unsigned len)
-{
- while (len--)
- BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_16 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero. Negating low-order words
- * entails doing nothing until a non-zero word is hit. Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit. Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_16
-void
-lbnNeg_16(BNWORD16 *num, unsigned len)
-{
- assert(len);
-
- /* Skip low-order zero words */
- while (BIGLITTLE(*--num,*num) == 0) {
- if (!--len)
- return;
- LITTLE(num++;)
- }
- /* Negate the lowest-order non-zero word */
- *num = -*num;
- /* Complement all the higher-order words */
- while (--len) {
- BIGLITTLE(--num,++num);
- *num = ~*num;
- }
-}
-#endif /* !lbnNeg_16 */
-
-
-/*
- * lbnAdd1_16: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex. After adding the first carry, which may
- * be > 1, compare the sum and the carry. If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^16) which is larger than
- * the other input can possibly be. If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap. Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_16 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD32
-BNWORD16
-lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry)
-{
- BNWORD32 t;
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- t = (BNWORD32)BIGLITTLE(*--num,*num) + carry;
- BIGLITTLE(*num,*num++) = (BNWORD16)t;
- if ((t >> 16) == 0)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry)
-{
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif/* !lbnAdd1_16 */
-
-/*
- * lbnSub1_16: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above. If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry. If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow. If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0. To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD16). If the size of an int is larger
- * than BNWORD16, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_16 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD32
-BNWORD16
-lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow)
-{
- BNWORD32 t;
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- t = (BNWORD32)BIGLITTLE(*--num,*num) - borrow;
- BIGLITTLE(*num,*num++) = (BNWORD16)t;
- if ((t >> 16) == 0)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow)
-{
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD16)~borrow)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif /* !lbnSub1_16 */
-
-/*
- * lbnAddN_16: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry. If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs. Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true. The first can
- * only be true if carry == 1 and x, the result, is 0. In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_16
-#ifdef BNWORD32
-BNWORD16
-lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
- BNWORD32 t;
-
- assert(len > 0);
-
- t = (BNWORD32)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
- while (--len) {
- t = (BNWORD32)BIGLITTLE(*--num1,*num1) +
- (BNWORD32)BIGLITTLE(*--num2,*num2++) + (t >> 16);
- BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
- }
-
- return (BNWORD16)(t>>16);
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
- BNWORD16 x, carry = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- carry = (x += carry) < carry;
- carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
- } while (--len);
-
- return carry;
-}
-#endif
-#endif /* !lbnAddN_16 */
-
-/*
- * lbnSubN_16: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again. Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true. The first can only be true if
- * borrow == 1 and x, the result, is 0. In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD16)-(t>>16) is subtracted, rather than
- * adding t>>16, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_16
-#ifdef BNWORD32
-BNWORD16
-lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
- BNWORD32 t;
-
- assert(len > 0);
-
- t = (BNWORD32)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
-
- while (--len) {
- t = (BNWORD32)BIGLITTLE(*--num1,*num1) -
- (BNWORD32)BIGLITTLE(*--num2,*num2++) - (BNWORD16)-(t >> 16);
- BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
- }
-
- return -(BNWORD16)(t>>16);
-}
-#else
-BNWORD16
-lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
- BNWORD16 x, borrow = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- borrow = (x += borrow) < borrow;
- borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD16)~x;
- } while (--len);
-
- return borrow;
-}
-#endif
-#endif /* !lbnSubN_16 */
-
-#ifndef lbnCmp_16
-/*
- * lbnCmp_16: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- *
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_16(BNWORD16 const *num1, BNWORD16 const *num2, unsigned len)
-{
- BIGLITTLE(num1 -= len, num1 += len);
- BIGLITTLE(num2 -= len, num2 += len);
-
- while (len--) {
- if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
- if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
- return -1;
- else
- return 1;
- }
- }
- return 0;
-}
-#endif /* !lbnCmp_16 */
-
-/*
- * mul16_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b. mul16_ppmma and mul16_ppmm
- * are simpler versions. If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul16_ppmma) && defined(mul16_ppmmaa)
-#define mul16_ppmma(ph,pl,x,y,a) mul16_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul16_ppmm) && defined(mul16_ppmma)
-#define mul16_ppmm(ph,pl,x,y) mul16_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul16_ppmm-based operations on machines
- * that do not provide mul16_ppmm. Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul16_ppmm) && defined(BNWORD32) && 0 /* Debugging */
-#define mul16_ppmm(ph,pl,x,y) \
- ({BNWORD32 _ = (BNWORD32)(x)*(y); (pl) = _; (ph) = _>>16;})
-#endif
-
-#if defined(mul16_ppmm) && !defined(mul16_ppmma)
-#define mul16_ppmma(ph,pl,x,y,a) \
- (mul16_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul16_ppmma) && !defined(mul16_ppmmaa)
-#define mul16_ppmmaa(ph,pl,x,y,a,b) \
- (mul16_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_16: Multiply an n-word input by a 1-word input and store the
- * n+1-word product. This uses either the mul16_ppmm and mul16_ppmma
- * macros, or C multiplication with the BNWORD32 type. This uses mul16_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_16
-#ifdef lbnMulAdd1_16 /* If we have this asm primitive, use it. */
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- lbnZero_16(out, len);
- BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_16(out, in, len, k);
-}
-#elif defined(mul16_ppmm)
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD16 carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- mul16_ppmm(carry, *out, *in, k);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;)
- carryin = carry;
- mul16_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
- }
- BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD32)
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD32 p;
-
- assert(len > 0);
-
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k;
- BIGLITTLE(*--out,*out++) = (BNWORD16)p;
-
- while (--len) {
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + (BNWORD16)(p >> 16);
- BIGLITTLE(*--out,*out++) = (BNWORD16)p;
- }
- BIGLITTLE(*--out,*out) = (BNWORD16)(p >> 16);
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* lbnMulN1_16 */
-
-/*
- * lbnMulAdd1_16: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination. *Returns the n+1st word
- * of the product.* (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.) This uses either the mul16_ppmma and mul16_ppmmaa macros,
- * or C multiplication with the BNWORD32 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with. It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_16
-#if defined(mul16_ppmm)
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD16 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- carryin = *out;
- mul16_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;);
- carryin = carry;
- mul16_ppmmaa(carry, prod, *in, k, carryin, *out);
- *out = prod;
- LITTLE(out++;in++;)
- }
-
- return carry;
-}
-#elif defined(BNWORD32)
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD32 p;
-
- assert(len > 0);
-
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD16)p;
-
- while (--len) {
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k +
- (BNWORD16)(p >> 16) + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD16)p;
- }
-
- return (BNWORD16)(p >> 16);
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* lbnMulAdd1_16 */
-
-/*
- * lbnMulSub1_16: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination. Returns the n+1st word of the product.
- * This uses either the mul16_ppmm and mul16_ppmma macros, or
- * C multiplication with the BNWORD32 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_16
-#if defined(mul16_ppmm)
-BNWORD16
-lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD16 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--in;)
- mul16_ppmm(carry, prod, *in, k);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD16)~prod;
-
- while (--len) {
- BIG(--in;);
- carryin = carry;
- mul16_ppmma(carry, prod, *in, k, carryin);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD16)~prod;
- }
-
- return carry;
-}
-#elif defined(BNWORD32)
-BNWORD16
-lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
- BNWORD32 p;
- BNWORD16 carry, t;
-
- assert(len > 0);
-
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD16)(p>>16) + ((BIGLITTLE(*out,*out++)=t-(BNWORD16)p) > t);
-
- while (--len) {
- p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + carry;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD16)(p>>16) +
- ( (BIGLITTLE(*out,*out++)=t-(BNWORD16)p) > t );
- }
-
- return carry;
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* !lbnMulSub1_16 */
-
-/*
- * Shift n words left "shift" bits. 0 < shift < 16. Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_16
-BNWORD16
-lbnLshift_16(BNWORD16 *num, unsigned len, unsigned shift)
-{
- BNWORD16 x, carry;
-
- assert(shift > 0);
- assert(shift < 16);
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<shift) | carry;
- LITTLE(num++;)
- carry = x >> (16-shift);
- }
- return carry;
-}
-#endif /* !lbnLshift_16 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_16
-BNWORD16
-lbnDouble_16(BNWORD16 *num, unsigned len)
-{
- BNWORD16 x, carry;
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<1) | carry;
- LITTLE(num++;)
- carry = x >> (16-1);
- }
- return carry;
-}
-#endif /* !lbnDouble_16 */
-
-/*
- * Shift n words right "shift" bits. 0 < shift < 16. Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_16
-BNWORD16
-lbnRshift_16(BNWORD16 *num, unsigned len, unsigned shift)
-{
- BNWORD16 x, carry = 0;
-
- assert(shift > 0);
- assert(shift < 16);
-
- BIGLITTLE(num -= len, num += len);
-
- while (len--) {
- LITTLE(--num;)
- x = *num;
- *num = (x>>shift) | carry;
- BIG(num++;)
- carry = x << (16-shift);
- }
- return carry >> (16-shift);
-}
-#endif /* !lbnRshift_16 */
-
-/*
- * Multiply two numbers of the given lengths. prod and num2 may overlap,
- * provided that the low len1 bits of prod are free. (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_16.)
- *
- * TODO: Use Karatsuba multiply. The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_16
-void
-lbnMul_16(BNWORD16 *prod, BNWORD16 const *num1, unsigned len1,
- BNWORD16 const *num2, unsigned len2)
-{
- /* Special case of zero */
- if (!len1 || !len2) {
- lbnZero_16(prod, len1+len2);
- return;
- }
-
- /* Multiply first word */
- lbnMulN1_16(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
- /*
- * Add in subsequent words, storing the most significant word,
- * which is new each time.
- */
- while (--len2) {
- BIGLITTLE(--prod,prod++);
- BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
- lbnMulAdd1_16(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
- }
-}
-#endif /* !lbnMul_16 */
-
-/*
- * lbnMulX_16 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_16
-#if defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster. It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_16(BNWORD16 *prod, BNWORD16 const *num1, BNWORD16 const *num2,
- unsigned len)
-{
- BNWORD32 x, y;
- BNWORD16 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- x = (BNWORD32)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD16)x;
- x >>= 16;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- for (j = 0; j <= i; j++) {
- BIG(y = (BNWORD32)*--p1 * *p2++;)
- LITTLE(y = (BNWORD32)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- for (j = i; j < len; j++) {
- BIG(y = (BNWORD32)*--p1 * *p2++;)
- LITTLE(y = (BNWORD32)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
-
- BIGLITTLE(*--prod,*prod) = (BNWORD16)x;
-}
-#else /* !defined(BNWORD32) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_16(prod, num1, num2, len) lbnMul_16(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD32) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_16 */
-
-#if !defined(lbnMontMul_16) && defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply. This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops. The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers. These are stored in the product array,
- * which contains no data as of yet. x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_16(BNWORD16 *prod, BNWORD16 const *num1, BNWORD16 const *num2,
- BNWORD16 const *mod, unsigned len, BNWORD16 inv)
-{
- BNWORD32 x, y;
- BNWORD16 const *p1, *p2, *pm;
- BNWORD16 *pp;
- BNWORD16 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /*
- * This computes directly into the high half of prod, so just
- * shift the pointer and consider prod only "len" elements long
- * for the rest of the code.
- */
- BIGLITTLE(prod -= len, prod += len);
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- x = (BNWORD32)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD16)x;
- y = (BNWORD32)t * BIGLITTLE(mod[-1],mod[0]);
- x += y;
- /* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
- carry = (x < y);
- assert((BNWORD16)x == 0);
- x = x >> 16 | (BNWORD32)carry << 16;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- pp = prod;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD32)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD32)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
- x += y;
- carry += (x < y);
- }
- y = (BNWORD32)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
- x += y;
- carry += (x < y);
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD16)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD32)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD16)x == 0);
- x = x >> 16 | (BNWORD32)carry << 16;
- }
-
- /* Pass 2 - compute reduced product and store */
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- pm = BIGLITTLE(mod-i,mod+i);
- pp = BIGLITTLE(prod-len,prod+len);
- for (j = i; j < len; j++) {
- y = (BNWORD32)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD32)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-len, pm == mod+len));
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[0],pp[-1]) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
-
- /* Last round of second half, simplified. */
- BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD16)x;
- carry = (x >> 16);
-
- while (carry)
- carry -= lbnSubN_16(prod, mod, len);
- while (lbnCmp_16(prod, mod, len) >= 0)
- (void)lbnSubN_16(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_16 lbnMontMul_16
-#endif
-
-#if !defined(lbnSquare_16) && defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring. This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len)
-{
- BNWORD32 x, y, z;
- BNWORD16 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /* Word 0 of product */
- x = (BNWORD32)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD16)x;
- x >>= 16;
-
- /* Words 1 through len-1 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = num;
- p2 = BIGLITTLE(num-i-1,num+i+1);
- for (j = 0; j < (i+1)/2; j++) {
- BIG(z = (BNWORD32)*--p1 * *p2++;)
- LITTLE(z = (BNWORD32)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((i & 1) == 0) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD32)*p2 * *p2;)
- LITTLE(z = (BNWORD32)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
- /* Words len through 2*len-2 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = BIGLITTLE(num-i,num+i);
- p2 = BIGLITTLE(num-len,num+len);
- for (j = 0; j < (len-i)/2; j++) {
- BIG(z = (BNWORD32)*--p1 * *p2++;)
- LITTLE(z = (BNWORD32)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((len-i) & 1) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD32)*p2 * *p2;)
- LITTLE(z = (BNWORD32)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
-
- /* Word 2*len-1 */
- BIGLITTLE(*--prod,*prod) = (BNWORD16)x;
-}
-/* Suppress later definition */
-#define lbnSquare_16 lbnSquare_16
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed. There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- * a b c d e
- * * a b c d e
- * ==================
- * ae be ce de ee
- * ad bd cd dd de
- * ac bc cc cd ce
- * ab bb bc bd be
- * aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- * ae be ce de = (abcd) * e
- * ad bd cd = (abc) * d
- * ac bc = (ab) * c
- * ab = (a) * b
- *
- * is a copy of everything below the main diagonal:
- * de
- * cd ce
- * bc bd be
- * ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again. The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba. (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_16
-void
-lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len)
-{
- BNWORD16 t;
- BNWORD16 *prodx = prod; /* Working copy of the argument */
- BNWORD16 const *numx = num; /* Working copy of the argument */
- unsigned lenx = len; /* Working copy of the argument */
-
- if (!len)
- return;
-
- /* First, store all the squares */
- while (lenx--) {
-#ifdef mul16_ppmm
- BNWORD16 ph, pl;
- t = BIGLITTLE(*--numx,*numx++);
- mul16_ppmm(ph,pl,t,t);
- BIGLITTLE(*--prodx,*prodx++) = pl;
- BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD32) /* use BNWORD32 */
- BNWORD32 p;
- t = BIGLITTLE(*--numx,*numx++);
- p = (BNWORD32)t * t;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD16)p;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD16)(p>>16);
-#else /* Use lbnMulN1_16 */
- t = BIGLITTLE(numx[-1],*numx);
- lbnMulN1_16(prodx, numx, 1, t);
- BIGLITTLE(--numx,numx++);
- BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
- }
- /* Then, shift right 1 bit */
- (void)lbnRshift_16(prod, 2*len, 1);
-
- /* Then, add in the off-diagonal sums */
- lenx = len;
- numx = num;
- prodx = prod;
- while (--lenx) {
- t = BIGLITTLE(*--numx,*numx++);
- BIGLITTLE(--prodx,prodx++);
- t = lbnMulAdd1_16(prodx, numx, lenx, t);
- lbnAdd1_16(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
- BIGLITTLE(--prodx,prodx++);
- }
-
- /* Shift it back up */
- lbnDouble_16(prod, 2*len);
-
- /* And set the low bit appropriately */
- BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_16 */
-
-/*
- * lbnNorm_16 - given a number, return a modified length such that the
- * most significant digit is non-zero. Zero-length input is okay.
- */
-#ifndef lbnNorm_16
-unsigned
-lbnNorm_16(BNWORD16 const *num, unsigned len)
-{
- BIGLITTLE(num -= len,num += len);
- while (len && BIGLITTLE(*num++,*--num) == 0)
- --len;
- return len;
-}
-#endif /* lbnNorm_16 */
-
-/*
- * lbnBits_16 - return the number of significant bits in the array.
- * It starts by normalizing the array. Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 16, and
- * subtracts off 16/2, 16/4, 16/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_16
-unsigned
-lbnBits_16(BNWORD16 const *num, unsigned len)
-{
- BNWORD16 t;
- unsigned i;
-
- len = lbnNorm_16(num, len);
- if (len) {
- t = BIGLITTLE(*(num-len),*(num+(len-1)));
- assert(t);
- len *= 16;
- i = 16/2;
- do {
- if (t >> i)
- t >>= i;
- else
- len -= i;
- } while ((i /= 2) != 0);
- }
- return len;
-}
-#endif /* lbnBits_16 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 16 bits, which a general 32-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_32
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_32 (32 > 0x20)
-#endif
-
-/*
- * Return (nh<<16|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set). If we have a double-width type, it's easy. If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_16
-#if defined(BNWORD32) && !BN_SLOW_DIVIDE_32
-BNWORD16
-lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d)
-{
- BNWORD32 n = (BNWORD32)nh << 16 | nl;
-
- /* Divisor must be normalized */
- assert(d >> (16-1) == 1);
-
- *q = n / d;
- return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth. Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- * _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- * - (qh * d)
- * -----------
- * rrrr rrrr nl.l
- * - (ql * d)
- * -----------
- * rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- * First, estimate a q digit so that nh/dh works. Subtracting qh*dh from
- * the (nh.h nh.l) list leaves a 1/2-word remainder r. Then compute the
- * low part of the subtractor, qh * dl. This also needs to be subtracted
- * from (nh.h nh.l nl.h) to get the final remainder. So we take the
- * remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- * try to subtract qh * dl from that. Since the remainder is 1/2-word
- * long, shifting and adding nl.h results in a single word r.
- * It is possible that the remainder we're working with, r, is less than
- * the product qh * dl, if we estimated qh too high. The estimation
- * technique can produce a qh that is too large (never too small), leading
- * to r which is too small. In that case, decrement the digit qh, add
- * shifted dh to r (to correct for that error), and subtract dl from the
- * product we're comparing r with. That's the "correct" way to do it, but
- * just adding dl to r instead of subtracting it from the product is
- * equivalent and a lot simpler. You just have to watch out for overflow.
- *
- * The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- * quotient ql.
- *
- * The various uses of 16/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 16/2 )
-#define lowhalf(x) ( (x) & (((BNWORD16)1 << 16/2)-1) )
-BNWORD16
-lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d)
-{
- BNWORD16 dh = highhalf(d), dl = lowhalf(d);
- BNWORD16 qh, ql, prod, r;
-
- /* Divisor must be normalized */
- assert((d >> (16-1)) == 1);
-
- /* Do first half-word of division */
- qh = nh / dh;
- r = nh % dh;
- prod = qh * dl;
-
- /*
- * Add next half-word of numerator to remainder and correct.
- * qh may be up to two too large.
- */
- r = (r << (16/2)) | highhalf(nl);
- if (r < prod) {
- --qh; r += d;
- if (r >= d && r < prod) {
- --qh; r += d;
- }
- }
- r -= prod;
-
- /* Do second half-word of division */
- ql = r / dh;
- r = r % dh;
- prod = ql * dl;
-
- r = (r << (16/2)) | lowhalf(nl);
- if (r < prod) {
- --ql; r += d;
- if (r >= d && r < prod) {
- --ql; r += d;
- }
- }
- r -= prod;
-
- *q = (qh << (16/2)) | ql;
-
- return r;
-}
-#endif
-#endif /* lbnDiv21_16 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long. It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient. The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_32, add a divnhalf_16 which uses 16-bit
- * dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- * instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_16
-BNWORD16
-lbnDiv1_16(BNWORD16 *q, BNWORD16 *rem, BNWORD16 const *n, unsigned len,
- BNWORD16 d)
-{
- unsigned shift;
- unsigned xlen;
- BNWORD16 r;
- BNWORD16 qhigh;
-
- assert(len > 0);
- assert(d);
-
- if (len == 1) {
- r = *n;
- *rem = r%d;
- return r/d;
- }
-
- shift = 0;
- r = d;
- xlen = 16/2;
- do {
- if (r >> xlen)
- r >>= xlen;
- else
- shift += xlen;
- } while ((xlen /= 2) != 0);
- assert((d >> (16-1-shift)) == 1);
- d <<= shift;
-
- BIGLITTLE(q -= len-1,q += len-1);
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r < d) {
- qhigh = 0;
- } else {
- qhigh = r/d;
- r %= d;
- }
-
- xlen = len;
- while (--xlen)
- r = lbnDiv21_16(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift) {
- d >>= shift;
- qhigh = (qhigh << shift) | lbnLshift_16(q, len-1, shift);
- BIGLITTLE(q[-1],*q) |= r/d;
- r %= d;
- }
- *rem = r;
-
- return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_16
-/* If there's a custom lbnMod21_16, no normalization needed */
-#ifdef lbnMod21_16
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD16 r;
-
- assert(len > 0);
-
- BIGLITTLE(n -= len,n += len);
-
- /* Try using a compare to avoid the first divide */
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
- while (--len)
- r = lbnMod21_16(r, BIGLITTLE(*n++,*--n), d);
-
- return r;
-}
-#elif defined(BNWORD32) && !BN_SLOW_DIVIDE_32
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
- BNWORD16 r;
-
- if (!--len)
- return BIGLITTLE(n[-1],n[0]) % d;
-
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(n[-1],n[0]);
-
- do {
- r = (BNWORD16)((((BNWORD32)r<<16) | BIGLITTLE(*n++,*--n)) % d);
- } while (--len);
-
- return r;
-}
-#elif 16 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 16/2 )
-#define lowhalf(x) ( (x) & ((1 << 16/2)-1) )
-#endif
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
- BNWORD16 r, x;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- while (--len) {
- x = BIGLITTLE(*n++,*--n);
- r = (r%d << 16/2) | highhalf(x);
- r = (r%d << 16/2) | lowhalf(x);
- }
-
- return r%d;
-}
-#else
-/* Default case - use lbnDiv21_16 */
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD16 r;
- BNWORD16 q;
-
- assert(len > 0);
-
- shift = 0;
- r = d;
- i = 16;
- while (i /= 2) {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- }
- assert(d >> (16-1-shift) == 1);
- d <<= shift;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
-
- while (--len)
- r = lbnDiv21_16(&q, r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift)
- r %= d >> shift;
-
- return r;
-}
-#endif
-#endif /* lbnModQ_16 */
-
-/*
- * Reduce n mod d and return the quotient. That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long. To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor. WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction. This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount. This will produce the
- * correct quotient, and the remainder can be recovered by shifting
- * it back down the same number of bits. This may produce an overflow
- * word, but the word is always strictly less than the most significant
- * divisor word.
- * - Estimate the first quotient digit qhat:
- * - First take the top two words (one of which is the overflow) of the
- * dividend and divide by the top word of the divisor:
- * qhat = (nh,nm)/dh. This qhat is >= the correct quotient digit
- * and, since dh is normalized, it is at most two over.
- * - Second, correct by comparing the top three words. If
- * (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- * The second iteration can be simpler because there can't be a third.
- * The computation can be simplified by subtracting dh*qhat from
- * both sides, suitably shifted. This reduces the left side to
- * dl*qhat. On the right, (nh,nm)-dh*qhat is simply the
- * remainder r from (nh,nm)%dh, so the right is (r,nl).
- * This produces qhat that is almost always correct and at
- * most (prob ~ 2/2^16) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- * If there is a borrow, qhat was wrong, so decrement it
- * and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed. Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_16
-BNWORD16
-lbnDiv_16(BNWORD16 *q, BNWORD16 *n, unsigned nlen, BNWORD16 *d, unsigned dlen)
-{
- BNWORD16 nh,nm,nl; /* Top three words of the dividend */
- BNWORD16 dh,dl; /* Top two words of the divisor */
- BNWORD16 qhat; /* Extimate of quotient word */
- BNWORD16 r; /* Remainder from quotient estimate division */
- BNWORD16 qhigh; /* High word of quotient */
- unsigned i; /* Temp */
- unsigned shift; /* Bits shifted by normalization */
- unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul16_ppmm
- BNWORD16 t16;
-#elif defined(BNWORD32)
- BNWORD32 t32;
-#else /* use lbnMulN1_16 */
- BNWORD16 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
- assert(dlen);
- assert(nlen >= dlen);
-
- /*
- * Special cases for short divisors. The general case uses the
- * top top 2 digits of the divisor (d) to estimate a quotient digit,
- * so it breaks if there are fewer digits available. Thus, we need
- * special cases for a divisor of length 1. A divisor of length
- * 2 can have a *lot* of administrivia overhead removed removed,
- * so it's probably worth special-casing that case, too.
- */
- if (dlen == 1)
- return lbnDiv1_16(q, BIGLITTLE(n-1,n), n, nlen,
- BIGLITTLE(d[-1],d[0]));
-
-#if 0
- /*
- * @@@ This is not yet written... The general loop will do,
- * albeit less efficiently
- */
- if (dlen == 2) {
- /*
- * divisor two digits long:
- * use the 3/2 technique from Knuth, but we know
- * it's exact.
- */
- dh = BIGLITTLE(d[-1],d[0]);
- dl = BIGLITTLE(d[-2],d[1]);
- shift = 0;
- if ((sh & ((BNWORD16)1 << 16-1-shift)) == 0) {
- do {
- shift++;
- } while (dh & (BNWORD16)1<<16-1-shift) == 0);
- dh = dh << shift | dl >> (16-shift);
- dl <<= shift;
-
-
- }
-
-
- for (shift = 0; (dh & (BNWORD16)1 << 16-1-shift)) == 0; shift++)
- ;
- if (shift) {
- }
- dh = dh << shift | dl >> (16-shift);
- shift = 0;
- while (dh
- }
-#endif
-
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- assert(dh);
-
- /* Normalize the divisor */
- shift = 0;
- r = dh;
- i = 16/2;
- do {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- } while ((i /= 2) != 0);
-
- nh = 0;
- if (shift) {
- lbnLshift_16(d, dlen, shift);
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- nh = lbnLshift_16(n, nlen, shift);
- }
-
- /* Assert that dh is now normalized */
- assert(dh >> (16-1));
-
- /* Also get the second-most significant word of the divisor */
- dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
- /*
- * Adjust pointers: n to point to least significant end of first
- * first subtract, and q to one the most-significant end of the
- * quotient array.
- */
- BIGLITTLE(n -= qlen,n += qlen);
- BIGLITTLE(q -= qlen,q += qlen);
-
- /* Fetch the most significant stored word of the dividend */
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- /*
- * Compute the first digit of the quotient, based on the
- * first two words of the dividend (the most significant of which
- * is the overflow word h).
- */
- if (nh) {
- assert(nh < dh);
- r = lbnDiv21_16(&qhat, nh, nm, dh);
- } else if (nm >= dh) {
- qhat = nm/dh;
- r = nm % dh;
- } else { /* Quotient is zero */
- qhigh = 0;
- goto divloop;
- }
-
- /* Now get the third most significant word of the dividend */
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
- /*
- * Correct qhat, the estimate of quotient digit.
- * qhat can only be high, and at most two words high,
- * so the loop can be unrolled and abbreviated.
- */
-#ifdef mul16_ppmm
- mul16_ppmm(nm, t16, qhat, dl);
- if (nm > r || (nm == r && t16 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t16 < dl);
- t16 -= dl;
- if (nm > r || (nm == r && t16 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD32)
- t32 = (BNWORD32)qhat * dl;
- if (t32 > ((BNWORD32)r << 16) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) > dh) {
- t32 -= dl;
- if (t32 > ((BNWORD32)r << 16) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_16 */
- lbnMulN1_16(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /* Do the multiply and subtract */
- r = lbnMulSub1_16(n, d, dlen, qhat);
- /* If there was a borrow, add back once. */
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_16(n, d, dlen);
- qhat--;
- }
-
- /* Remember the first quotient digit. */
- qhigh = qhat;
-
- /* Now, the main division loop: */
-divloop:
- while (qlen--) {
-
- /* Advance n */
- nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- BIGLITTLE(++n,--n);
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- if (nh == dh) {
- qhat = ~(BNWORD16)0;
- /* Optimized computation of r = (nh,nm) - qhat * dh */
- r = nh + nm;
- if (r < nh)
- goto subtract;
- } else {
- assert(nh < dh);
- r = lbnDiv21_16(&qhat, nh, nm, dh);
- }
-
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul16_ppmm
- mul16_ppmm(nm, t16, qhat, dl);
- if (nm > r || (nm == r && t16 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t16 < dl);
- t16 -= dl;
- if (nm > r || (nm == r && t16 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD32)
- t32 = (BNWORD32)qhat * dl;
- if (t32 > ((BNWORD32)r<<16) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t32 -= dl;
- if (t32 > ((BNWORD32)r << 16) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_16 */
- lbnMulN1_16(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /*
- * As a point of interest, note that it is not worth checking
- * for qhat of 0 or 1 and installing special-case code. These
- * occur with probability 2^-16, so spending 1 cycle to check
- * for them is only worth it if we save more than 2^15 cycles,
- * and a multiply-and-subtract for numbers in the 1024-bit
- * range just doesn't take that long.
- */
-subtract:
- /*
- * n points to the least significant end of the substring
- * of n to be subtracted from. qhat is either exact or
- * one too large. If the subtract gets a borrow, it was
- * one too large and the divisor is added back in. It's
- * a dlen+1 word add which is guaranteed to produce a
- * carry out, so it can be done very simply.
- */
- r = lbnMulSub1_16(n, d, dlen, qhat);
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_16(n, d, dlen);
- qhat--;
- }
- /* Store the quotient digit */
- BIGLITTLE(*q++,*--q) = qhat;
- }
- /* Tah dah! */
-
- if (shift) {
- lbnRshift_16(d, dlen, shift);
- lbnRshift_16(n, dlen, shift);
- }
-
- return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^16.
- *
- * This just performs Newton's iteration until it gets the
- * inverse. The initial estimate is always correct to 3 bits, and
- * sometimes 4. The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n. x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_16
-BNWORD16
-lbnMontInv1_16(BNWORD16 const x)
-{
- BNWORD16 y = x, z;
-
- assert(x & 1);
-
- while ((z = x*y) != 1)
- y *= 2 - z;
- return -y;
-}
-#endif /* !lbnMontInv1_16 */
-
-#if defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned mlen, BNWORD16 inv)
-{
- BNWORD32 x, y;
- BNWORD16 const *pm;
- BNWORD16 *pn;
- BNWORD16 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!mlen)
- return;
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- t = BIGLITTLE(n[-1],n[0]);
- x = t;
- t *= inv;
- BIGLITTLE(n[-1], n[0]) = t;
- x += (BNWORD32)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
- assert((BNWORD16)x == 0);
- x = x >> 16;
-
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pn = n;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD32)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pn == n-i, pn == n+i));
- y = t = BIGLITTLE(pn[-1], pn[0]);
- x += y;
- carry += (x < y);
- BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD16)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD32)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD16)x == 0);
- x = x >> 16 | (BNWORD32)carry << 16;
- }
-
- BIGLITTLE(n -= mlen, n += mlen);
-
- /* Pass 2 - compute upper words and add to n */
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pm = BIGLITTLE(mod-i,mod+i);
- pn = n;
- for (j = i; j < mlen; j++) {
- y = (BNWORD32)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
- assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
- y = t = BIGLITTLE(*(n-i),*(n+i-1));
- x += y;
- carry += (x < y);
- BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD16)x;
- x = (x >> 16) | (BNWORD32)carry << 16;
- }
-
- /* Last round of second half, simplified. */
- t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
- x += t;
- BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD16)x;
- carry = (unsigned)(x >> 16);
-
- while (carry)
- carry -= lbnSubN_16(n, mod, mlen);
- while (lbnCmp_16(n, mod, mlen) >= 0)
- (void)lbnSubN_16(n, mod, mlen);
-}
-#define lbnMontReduce_16 lbnMontReduce_16
-#endif
-
-/*
- * Montgomery reduce n, modulo mod. This reduces modulo mod and divides by
- * 2^(16*mlen). Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_16.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction. What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift. In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(16*mlen). Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc. Note that:
- * - The Montgomery form of a number depends on the modulus m.
- * A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- * no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- * M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R. The problem
- * is to divide out the excess factor of R, modulo m as well as to
- * reduce to the given length mlen. It turns out that this can be
- * done *faster* than a normal divide, which is where the speedup
- * in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced. Choosing q is tricky
- * and involved (just look at lbnDiv_16 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced. This multiple is chosen to make the
- * low-order part of the number come out to zero. This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R. Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication. To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- *
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_16
-void
-lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned const mlen,
- BNWORD16 inv)
-{
- BNWORD16 t;
- BNWORD16 c = 0;
- unsigned len = mlen;
-
- /* inv must be the negative inverse of mod's least significant word */
- assert((BNWORD16)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD16)-1);
-
- assert(len);
-
- do {
- t = lbnMulAdd1_16(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
- c += lbnAdd1_16(BIGLITTLE(n-mlen,n+mlen), len, t);
- BIGLITTLE(--n,++n);
- } while (--len);
-
- /*
- * All that adding can cause an overflow past the modulus size,
- * but it's unusual, and never by much, so a subtraction loop
- * is the right way to deal with it.
- * This subtraction happens infrequently - I've only ever seen it
- * invoked once per reduction, and then just under 22.5% of the time.
- */
- while (c)
- c -= lbnSubN_16(n, mod, mlen);
- while (lbnCmp_16(n, mod, mlen) >= 0)
- (void)lbnSubN_16(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_16 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_16
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod". "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^16.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_16(prod, n1, n2, mod, len, inv) \
- (lbnMulX_16(prod, n1, n2, len), lbnMontReduce_16(prod, mod, len, inv))
-#endif /* !lbnMontMul_16 */
-
-#ifndef lbnMontSquare_16
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod". "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^16.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_16(prod, n, mod, len, inv) \
- (lbnSquare_16(prod, n, len), lbnMontReduce_16(prod, mod, len, inv))
-
-#endif /* !lbnMontSquare_16 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_16(BNWORD16 *n, unsigned nlen, BNWORD16 *mod, unsigned mlen)
-{
- /* Move n up "mlen" words */
- lbnCopy_16(BIGLITTLE(n-mlen,n+mlen), n, nlen);
- lbnZero_16(n, mlen);
- /* Do the division - dump the quotient in the high-order words */
- (void)lbnDiv_16(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form. Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_16(BNWORD16 *n, BNWORD16 *mod, unsigned len)
-{
- /* Zero the high words of n */
- lbnZero_16(BIGLITTLE(n-len,n+len), len);
- lbnMontReduce_16(n, mod, len, lbnMontInv1_16(mod[BIGLITTLE(-1,0)]));
- /* Move n down len words */
- lbnCopy_16(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k. See the comment in bnExpMod_16 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation. To minimize
- * the sum, k must vary with e. The optimal window sizes vary with the
- * exponent length. Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 16 do not appear in this table. It should be
- * ignored.)
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 8 bits, k=2 (3.333333) < k=1 (3.500000)
- * At e = 1_6 bits, k=2 (6.000000) is best
- * At e = 26 bits, k=3 (9.250000) < k=2 (9.333333)
- * At e = 3_2 bits, k=3 (10.750000) is best
- * At e = 6_4 bits, k=3 (18.750000) is best
- * At e = 82 bits, k=4 (23.200000) < k=3 (23.250000)
- * At e = 128 bits, k=4 (3_2.400000) is best
- * At e = 242 bits, k=5 (55.1_66667) < k=4 (55.200000)
- * At e = 256 bits, k=5 (57.500000) is best
- * At e = 512 bits, k=5 (100.1_66667) is best
- * At e = 674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation. The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2. For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5. Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings. It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case. Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all. Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 6 bits, k=2 (2.437500) < k=1 (2.500000)
- * At e = 8 bits, k=2 (3.109375) is best
- * At e = 1_6 bits, k=2 (5.777771) is best
- * At e = 24 bits, k=3 (8.437629) < k=2 (8.444444)
- * At e = 3_2 bits, k=3 (10.437492) is best
- * At e = 6_4 bits, k=3 (18.437500) is best
- * At e = 81 bits, k=4 (22.6_40000) < k=3 (22.687500)
- * At e = 128 bits, k=4 (3_2.040000) is best
- * At e = 241 bits, k=5 (54.611111) < k=4 (54.6_40000)
- * At e = 256 bits, k=5 (57.111111) is best
- * At e = 512 bits, k=5 (99.777778) is best
- * At e = 673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794. Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here. It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables. Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1. Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW 7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
- 5, 23, 80, 240, 672, 1792, (unsigned)-1
-/* 7, 25, 81, 241, 673, 1793, (unsigned)-1 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible! This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it. The following patterns
- * apply to a 3-bit window (k = 3):
- * To append 0: square
- * To append 1: square, multiply by n^1
- * To append 10: square, multiply by n^1, square
- * To append 11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time. Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/16 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes. There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits. (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it. We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away. Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings. 1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1. The average of these is 1. Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies. (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated. Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_16(BNWORD16 *result, BNWORD16 const *n, unsigned nlen,
- BNWORD16 const *e, unsigned elen, BNWORD16 *mod, unsigned mlen)
-{
- BNWORD16 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n */
- unsigned ebits; /* Exponent bits */
- unsigned wbits; /* Window size */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD16 bitpos; /* Mask of current look-ahead bit */
- unsigned buf; /* Buffer of exponent bits */
- unsigned multpos; /* Where to do pending multiply */
- BNWORD16 const *mult; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD16 *a, *b; /* Working buffers/accumulators */
- BNWORD16 *t; /* Pointer into the working buffers */
- BNWORD16 inv; /* mod^-1 modulo 2^16 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(nlen <= mlen);
-
- /* First, a couple of trivial cases. */
- elen = lbnNorm_16(e, elen);
- if (!elen) {
- /* x ^ 0 == 1 */
- lbnZero_16(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- ebits = lbnBits_16(e, elen);
- if (ebits == 1) {
- /* x ^ 1 == x */
- if (n != result)
- lbnCopy_16(result, n, nlen);
- if (mlen > nlen)
- lbnZero_16(BIGLITTLE(result-nlen,result+nlen),
- mlen-nlen);
- return 0;
- }
-
- /* Okay, now move the exponent pointer to the most-significant word */
- e = BIGLITTLE(e-elen, e+elen-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- wbits = 0;
- while (ebits > bnExpModThreshTable[wbits])
- wbits++;
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD16, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD16, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << wbits;
-
- /* We have the result buffer available, so use it. */
- table[0] = result;
-
- /*
- * Okay, we now have a minimal-sized table - expand it.
- * This is allowed to fail! If so, scale back the table size
- * and proceed.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD16, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table[i] = t;
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- wbits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask)
- LBNFREE(table[i], mlen);
-
- /* Okay, fill in the table */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n to Montgomery form */
-
- /* Move n up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_16(t, n, nlen);
- lbnZero_16(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_16(t, a, mlen+nlen, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_16(table[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_16(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_16(a, t, table[i-1], mod, mlen, inv);
- lbnCopy_16(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* We might use b = n^2 later... */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD16)1 << ((ebits-1) & (16-1)); /* Initialize mask */
-
- /* This should point to the msbit of e */
- assert((*e & bitpos) != 0);
-
- /*
- * Pre-load the window. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e in here.
- *
- * The read-ahead is controlled by elen and the bitpos mask.
- * Note that this is *ahead* of ebits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two wbits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- */
- buf = 0;
- for (i = 0; i <= wbits; i++) {
- buf = (buf << 1) | ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD16)1 << (16-1);
- elen--;
- }
- }
- assert(buf & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- multpos = ebits; /* A NULL value */
- mult = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- ebits--; /* Start processing the first bit... */
- isone = 1;
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf is set, and
- * - We have the extra value n^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf & tblmask);
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (multpos == ebits)
- isone = 0;
-
- /*
- * At this point, the buffer (which is the high half of b) holds
- * either 1 (implicitly, as the "isone" flag is set), or n^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the window
- * - If the most-significant bit of the window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffer
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- ebits--;
-
- /* Advance the window */
- assert(buf < tblmask);
- buf <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by ebits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (elen) {
- buf |= ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD16)1 << (16-1);
- elen--;
- }
- }
-
- /* Examine the window for pending multiplies */
- if (buf & tblmask) {
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
- }
-
- /* If we have a pending multiply, do it */
- if (ebits == multpos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_16(t, mult, mlen);
- isone = 0;
- } else {
- lbnMontMul_16(a, t, mult, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!ebits)
- break;
-
- /* Square the input */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_16(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_16(b, t, mlen);
- lbnZero_16(t, mlen);
- lbnMontReduce_16(b, mod, mlen, inv);
- lbnCopy_16(result, t, mlen);
- /*
- * Clean up - free intermediate storage.
- * Do NOT free table[0], which is the result
- * buffer.
- */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- while (--tblmask)
- LBNFREE(table[tblmask], mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1). When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place. Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future. But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading. The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_16(BNWORD16 *result,
- BNWORD16 const *n1, unsigned n1len,
- BNWORD16 const *e1, unsigned e1len,
- BNWORD16 const *n2, unsigned n2len,
- BNWORD16 const *e2, unsigned e2len,
- BNWORD16 *mod, unsigned mlen)
-{
- BNWORD16 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n1 */
- BNWORD16 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n2 */
- unsigned e1bits, e2bits; /* Exponent bits */
- unsigned w1bits, w2bits; /* Window sizes */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD16 bitpos; /* Mask of current look-ahead bit */
- unsigned buf1, buf2; /* Buffer of exponent bits */
- unsigned mult1pos, mult2pos; /* Where to do pending multiply */
- BNWORD16 const *mult1, *mult2; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD16 *a, *b; /* Working buffers/accumulators */
- BNWORD16 *t; /* Pointer into the working buffers */
- BNWORD16 inv; /* mod^-1 modulo 2^16 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(n1len <= mlen);
- assert(n2len <= mlen);
-
- /* First, a couple of trivial cases. */
- e1len = lbnNorm_16(e1, e1len);
- e2len = lbnNorm_16(e2, e2len);
-
- /* Ensure that the first exponent is the longer */
- e1bits = lbnBits_16(e1, e1len);
- e2bits = lbnBits_16(e2, e2len);
- if (e1bits < e2bits) {
- i = e1len; e1len = e2len; e2len = i;
- i = e1bits; e1bits = e2bits; e2bits = i;
- t = (BNWORD16 *)n1; n1 = n2; n2 = t;
- t = (BNWORD16 *)e1; e1 = e2; e2 = t;
- }
- assert(e1bits >= e2bits);
-
- /* Handle a trivial case */
- if (!e2len)
- return lbnExpMod_16(result, n1, n1len, e1, e1len, mod, mlen);
- assert(e2bits);
-
- /* The code below fucks up if the exponents aren't at least 2 bits */
- if (e1bits == 1) {
- assert(e2bits == 1);
-
- LBNALLOC(a, BNWORD16, n1len+n2len);
- if (!a)
- return -1;
-
- lbnMul_16(a, n1, n1len, n2, n2len);
- /* Do a direct modular reduction */
- if (n1len + n2len >= mlen)
- (void)lbnDiv_16(a+mlen, a, n1len+n2len, mod, mlen);
- lbnCopy_16(result, a, mlen);
- LBNFREE(a, n1len+n2len);
- return 0;
- }
-
- /* Okay, now move the exponent pointers to the most-significant word */
- e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
- e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- w1bits = 0;
- while (e1bits > bnExpModThreshTable[w1bits])
- w1bits++;
- w2bits = 0;
- while (e2bits > bnExpModThreshTable[w2bits])
- w2bits++;
-
- assert(w1bits >= w2bits);
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD16, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD16, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << w1bits;
- /* Use buf2 for its size, temporarily */
- buf2 = 1u << w2bits;
-
- LBNALLOC(t, BNWORD16, mlen);
- if (!t) {
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return -1;
- }
- table1[0] = t;
- table2[0] = result;
-
- /*
- * Okay, we now have some minimal-sized tables - expand them.
- * This is allowed to fail! If so, scale back the table sizes
- * and proceed. We allocate both tables at the same time
- * so if it fails partway through, they'll both be a reasonable
- * size rather than one huge and one tiny.
- * When i passes buf2 (the number of entries in the e2 window,
- * which may be less than the number of entries in the e1 window),
- * stop allocating e2 space.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD16, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table1[i] = t;
- if (i < buf2) {
- LBNALLOC(t, BNWORD16, mlen);
- if (!t) {
- LBNFREE(table1[i], mlen);
- break;
- }
- table2[i] = t;
- }
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- w1bits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask) {
- if (i < buf2)
- LBNFREE(table2[i], mlen);
- LBNFREE(table1[i], mlen);
- }
- /* And shrink the second window too, if needed */
- if (w2bits > w1bits) {
- w2bits = w1bits;
- buf2 = tblmask;
- }
-
- /*
- * From now on, use the w2bits variable for the difference
- * between w1bits and w2bits.
- */
- w2bits = w1bits-w2bits;
-
- /* Okay, fill in the tables */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n1 to Montgomery form */
-
- /* Move n1 up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_16(t, n1, n1len);
- lbnZero_16(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_16(t, a, mlen+n1len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_16(table1[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_16(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the first table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_16(a, t, table1[i-1], mod, mlen, inv);
- lbnCopy_16(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* Convert n2 to Montgomery form */
-
- t = BIGLITTLE(a-mlen, a+mlen);
- /* Move n2 up "mlen" words into a */
- lbnCopy_16(t, n2, n2len);
- lbnZero_16(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_16(t, a, mlen+n2len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_16(table2[0], a, mlen);
-
- /* Square it into a */
- lbnMontSquare_16(a, table2[0], mod, mlen, inv);
- /* Copy to b, low half */
- lbnCopy_16(b, t, mlen);
-
- /* Use b to initialize the second table */
- for (i = 1; i < buf2; i++) {
- lbnMontMul_16(a, b, table2[i-1], mod, mlen, inv);
- lbnCopy_16(table2[i], t, mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /*
- * Okay, a recap: at this point, the low part of b holds
- * n2^2, the high part holds n1^2, and the tables are
- * initialized with the odd powers of n1 and n2 from 1
- * through 2*tblmask-1 and 2*buf2-1.
- *
- * We might use those squares in b later, or we might not.
- */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD16)1 << ((e1bits-1) & (16-1)); /* Initialize mask */
-
- /* This should point to the msbit of e1 */
- assert((*e1 & bitpos) != 0);
-
- /*
- * Pre-load the windows. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e1 in here.
- *
- * The read-ahead is controlled by e1len and the bitpos mask.
- * Note that this is *ahead* of e1bits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two w1bits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- * e2len is not decremented, it is only ever compared with
- * e1len as *that* is decremented.
- */
- buf1 = buf2 = 0;
- for (i = 0; i <= w1bits; i++) {
- buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD16)1 << (16-1);
- e1len--;
- }
- }
- assert(buf1 & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- mult1pos = mult2pos = e1bits; /* A NULL value */
- mult1 = mult2 = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- isone = 1; /* Buffer is implicitly 1, so replace * by copy */
- e1bits--; /* Start processing the first bit... */
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf1 is set, and
- * - We have the extra value n1^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n1^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n1^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf1 & tblmask);
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (mult1pos == e1bits)
- isone = 0;
-
- /*
- * The first multiply by a power of n2. Similar, but
- * we might not even want to schedule a multiply if e2 is
- * shorter than e1, and the window might be shorter so
- * we have to leave the low w2bits bits alone.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
-
- if (mult2pos == e1bits) {
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- lbnCopy_16(t, b, mlen); /* Copy low to high */
- isone = 0;
- } else {
- lbnMontMul_16(a, t, b, mod, mlen, inv);
- t = a; a = b; b = t;
- }
- }
- }
-
- /*
- * At this point, the buffer (which is the high half of b)
- * holds either 1 (implicitly, as the "isone" flag is set),
- * n1^2, n2^2 or n1^2 * n2^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the windows
- * - If the most-significant bit of a window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffers
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- e1bits--;
-
- /* Advance the windows */
- assert(buf1 < tblmask);
- buf1 <<= 1;
- assert(buf2 < tblmask);
- buf2 <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by e1bits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (e1len) {
- buf1 |= ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 |= ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD16)1 << (16-1);
- e1len--;
- }
- }
-
- /* Examine the first window for pending multiplies */
- if (buf1 & tblmask) {
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
- }
-
- /*
- * Examine the second window for pending multiplies.
- * Window 2 can be smaller than window 1, but we
- * keep the same number of bits in buf2, so we need
- * to ignore any low-order bits in the buffer when
- * computing what to multiply by, and recompute them
- * later.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
- }
-
-
- /* If we have a pending multiply for e1, do it */
- if (e1bits == mult1pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_16(t, mult1, mlen);
- isone = 0;
- } else {
- lbnMontMul_16(a, t, mult1, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* If we have a pending multiply for e2, do it */
- if (e1bits == mult2pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_16(t, mult2, mlen);
- isone = 0;
- } else {
- lbnMontMul_16(a, t, mult2, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!e1bits)
- break;
-
- /* Square the buffer */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_16(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf1);
- assert(!buf2);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_16(b, t, mlen);
- lbnZero_16(t, mlen);
- lbnMontReduce_16(b, mod, mlen, inv);
- lbnCopy_16(result, t, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- buf2 = tblmask >> w2bits;
- while (--tblmask) {
- if (tblmask < buf2)
- LBNFREE(table2[tblmask], mlen);
- LBNFREE(table1[tblmask], mlen);
- }
- t = table1[0];
- LBNFREE(t, mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * 2^exp (mod mod). This is an optimized version for use in Fermat
- * tests. The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_16(BNWORD16 *n, BNWORD16 const *exp, unsigned elen,
- BNWORD16 *mod, unsigned mlen)
-{
- unsigned e; /* Copy of high words of the exponent */
- unsigned bits; /* Assorted counter of bits */
- BNWORD16 const *bitptr;
- BNWORD16 bitword, bitpos;
- BNWORD16 *a, *b, *a1;
- BNWORD16 inv;
- int y; /* Result of bnYield() */
-
- assert(mlen);
-
- bitptr = BIGLITTLE(exp-elen, exp+elen-1);
- bitword = *bitptr;
- assert(bitword);
-
- /* Clear n for future use. */
- lbnZero_16(n, mlen);
-
- bits = lbnBits_16(exp, elen);
-
- /* First, a couple of trivial cases. */
- if (bits <= 1) {
- /* 2 ^ 0 == 1, 2 ^ 1 == 2 */
- BIGLITTLE(n[-1],n[0]) = (BNWORD16)1<<elen;
- return 0;
- }
-
- /* Set bitpos to the most significant bit */
- bitpos = (BNWORD16)1 << ((bits-1) & (16-1));
-
- /* Now, count the bits in the modulus. */
- bits = lbnBits_16(mod, mlen);
- assert(bits > 1); /* a 1-bit modulus is just stupid... */
-
- /*
- * We start with 1<<e, where "e" is as many high bits of the
- * exponent as we can manage without going over the modulus.
- * This first loop finds "e".
- */
- e = 1;
- while (elen) {
- /* Consume the first bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break;
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD16)1<<(16-1);
- }
- e = (e << 1) | ((bitpos & bitword) != 0);
- if (e >= bits) { /* Overflow! Back out. */
- e >>= 1;
- break;
- }
- }
- /*
- * The bit in "bitpos" being examined by the bit buffer has NOT
- * been consumed yet. This may be past the end of the exponent,
- * in which case elen == 1.
- */
-
- /* Okay, now, set bit "e" in n. n is already zero. */
- inv = (BNWORD16)1 << (e & (16-1));
- e /= 16;
- BIGLITTLE(n[-e-1],n[e]) = inv;
- /*
- * The effective length of n in words is now "e+1".
- * This is used a little bit later.
- */
-
- if (!elen)
- return 0; /* That was easy! */
-
- /*
- * We have now processed the first few bits. The next step
- * is to convert this to Montgomery form for further squaring.
- */
-
- /* Allocate working storage: two product buffers */
- LBNALLOC(a, BNWORD16, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD16, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_16(inv);
- /* Move n (length e+1, remember?) up "mlen" words into b */
- /* Note that we lie about a1 for a bit - it's pointing to b */
- a1 = BIGLITTLE(b-mlen,b+mlen);
- lbnCopy_16(a1, n, e+1);
- lbnZero_16(b, mlen);
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_16(a1, b, mlen+e+1, mod, mlen);
- /*
- * Now do the first squaring and modular reduction to put
- * the number up in a1 where it belongs.
- */
- lbnMontSquare_16(a, b, mod, mlen, inv);
- /* Fix up a1 to point to where it should go. */
- a1 = BIGLITTLE(a-mlen,a+mlen);
-
- /*
- * Okay, now, a1 holds the number being accumulated, and
- * b is a scratch register. Start working:
- */
- for (;;) {
- /*
- * Is the bit set? If so, double a1 as well.
- * A modular doubling like this is very cheap.
- */
- if (bitpos & bitword) {
- /*
- * Double the number. If there was a carry out OR
- * the result is greater than the modulus, subract
- * the modulus.
- */
- if (lbnDouble_16(a1, mlen) ||
- lbnCmp_16(a1, mod, mlen) > 0)
- (void)lbnSubN_16(a1, mod, mlen);
- }
-
- /* Advance to the next exponent bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break; /* Done! */
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD16)1<<(16-1);
- }
-
- /*
- * The elen/bitword/bitpos bit buffer is known to be
- * non-empty, i.e. there is at least one more unconsumed bit.
- * Thus, it's safe to square the number.
- */
- lbnMontSquare_16(b, a1, mod, mlen, inv);
- /* Rename result (in b) back to a (a1, really). */
- a1 = b; b = a; a = a1;
- a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* DONE! Just a little bit of cleanup... */
-
- /*
- * Convert result out of Montgomery form... this is
- * just a Montgomery reduction.
- */
- lbnCopy_16(a, a1, mlen);
- lbnZero_16(a1, mlen);
- lbnMontReduce_16(a, mod, mlen, inv);
- lbnCopy_16(n, a1, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_16(BNWORD16 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD16 t = 0; /* Needed to shut up uninitialized var warnings */
- unsigned shift;
-
- lsbyte += buflen;
-
- shift = (8 * lsbyte) % 16;
- lsbyte /= (16/8); /* Convert to word offset */
- BIGLITTLE(n -= lsbyte, n += lsbyte);
-
- if (shift)
- t = BIGLITTLE(n[-1],n[0]);
-
- while (buflen--) {
- if (!shift) {
- t = BIGLITTLE(*n++,*--n);
- shift = 16;
- }
- shift -= 8;
- *buf++ = (unsigned char)(t>>shift);
- }
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_16(BNWORD16 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD16 t = 0; /* Shut up uninitialized varibale warnings */
-
- lsbyte += buflen;
-
- BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (16/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 16;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *buf++;
- if ((--lsbyte % (16/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 16;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD16)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_16(BNWORD16 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD16 t = 0; /* Needed to shut up uninitialized var warnings */
-
- BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
- if (lsbyte % (16/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte % (16/8)) * 8 ;
- }
-
- while (buflen--) {
- if ((lsbyte++ % (16/8)) == 0)
- t = BIGLITTLE(*--n,*n++);
- *buf++ = (unsigned char)t;
- t >>= 8;
- }
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_16(BNWORD16 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD16 t = 0; /* Shut up uninitialized varibale warnings */
-
- /* Move to most-significant end */
- lsbyte += buflen;
- buf += buflen;
-
- BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (16/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 16;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *--buf;
- if ((--lsbyte % (16/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 16;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD16)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-#ifdef DEADCODE /* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "16/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_16(BNWORD16 *a, unsigned char const *b, unsigned blen)
-{
- BNWORD16 t;
- unsigned alen = (blen + (16/8-1))/(16/8);
- BIGLITTLE(a -= alen, a += alen);
-
- while (blen) {
- t = 0;
- do {
- t = t << 8 | *b++;
- } while (--blen & (16/8-1));
- BIGLITTLE(*a++,*--a) = t;
- }
- return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b. Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash. The return value
- * indicates which: 0 for a, and 1 for b. The length of the retult is
- * returned in rlen. Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_16(BNWORD16 *a, unsigned alen, BNWORD16 *b, unsigned blen,
- unsigned *rlen)
-{
-#if BNYIELD
- int y;
-#endif
- assert(alen >= blen);
-
- while (blen != 0) {
- (void)lbnDiv_16(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- alen = lbnNorm_16(a, blen);
- if (alen == 0) {
- *rlen = blen;
- return 1;
- }
- (void)lbnDiv_16(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- blen = lbnNorm_16(b, alen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- return y;
-#endif
- }
- *rlen = alen;
- return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1. Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod". It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_16(BNWORD16 *a, unsigned alen, BNWORD16 const *mod, unsigned mlen)
-{
- BNWORD16 *b; /* Hold a copy of mod during GCD reduction */
- BNWORD16 *p; /* Temporary for products added to t0 and t1 */
- BNWORD16 *t0, *t1; /* Inverse accumulators */
- BNWORD16 cy;
- unsigned blen, t0len, t1len, plen;
- int y;
-
- alen = lbnNorm_16(a, alen);
- if (!alen)
- return 1; /* No inverse */
-
- mlen = lbnNorm_16(mod, mlen);
-
- assert (alen <= mlen);
-
- /* Inverse of 1 is 1 */
- if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
- lbnZero_16(BIGLITTLE(a-alen,a+alen), mlen-alen);
- return 0;
- }
-
- /* Allocate a pile of space */
- LBNALLOC(b, BNWORD16, mlen+1);
- if (b) {
- /*
- * Although products are guaranteed to always be less than the
- * modulus, it can involve multiplying two 3-word numbers to
- * get a 5-word result, requiring a 6th word to store a 0
- * temporarily. Thus, mlen + 1.
- */
- LBNALLOC(p, BNWORD16, mlen+1);
- if (p) {
- LBNALLOC(t0, BNWORD16, mlen);
- if (t0) {
- LBNALLOC(t1, BNWORD16, mlen);
- if (t1)
- goto allocated;
- LBNFREE(t0, mlen);
- }
- LBNFREE(p, mlen+1);
- }
- LBNFREE(b, mlen+1);
- }
- return -1;
-
-allocated:
-
- /* Set t0 to 1 */
- t0len = 1;
- BIGLITTLE(t0[-1],t0[0]) = 1;
-
- /* b = mod */
- lbnCopy_16(b, mod, mlen);
- /* blen = mlen (implicitly) */
-
- /* t1 = b / a; b = b % a */
- cy = lbnDiv_16(t1, b, mlen, a, alen);
- *(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
- t1len = lbnNorm_16(t1, mlen-alen+1);
- blen = lbnNorm_16(b, alen);
-
- /* while (b > 1) */
- while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD16)1) {
- /* q = a / b; a = a % b; */
- if (alen < blen || (alen == blen && lbnCmp_16(a, a, alen) < 0))
- assert(0);
- cy = lbnDiv_16(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- *(BIGLITTLE(a-alen-1,a+alen)) = cy;
- plen = lbnNorm_16(BIGLITTLE(a-blen,a+blen), alen-blen+1);
- assert(plen);
- alen = lbnNorm_16(a, blen);
- if (!alen)
- goto failure; /* GCD not 1 */
-
- /* t0 += q * t1; */
- assert(plen+t1len <= mlen+1);
- lbnMul_16(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
- plen = lbnNorm_16(p, plen + t1len);
- assert(plen <= mlen);
- if (plen > t0len) {
- lbnZero_16(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
- t0len = plen;
- }
- cy = lbnAddN_16(t0, p, plen);
- if (cy) {
- if (t0len > plen) {
- cy = lbnAdd1_16(BIGLITTLE(t0-plen,t0+plen),
- t0len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
- t0len++;
- }
- }
-
- /* if (a <= 1) return a ? t0 : FAIL; */
- if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD16)1) {
- if (alen == 0)
- goto failure; /* FAIL */
- assert(t0len <= mlen);
- lbnCopy_16(a, t0, t0len);
- lbnZero_16(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
- goto success;
- }
-
- /* q = b / a; b = b % a; */
- if (blen < alen || (blen == alen && lbnCmp_16(b, a, alen) < 0))
- assert(0);
- cy = lbnDiv_16(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- *(BIGLITTLE(b-blen-1,b+blen)) = cy;
- plen = lbnNorm_16(BIGLITTLE(b-alen,b+alen), blen-alen+1);
- assert(plen);
- blen = lbnNorm_16(b, alen);
- if (!blen)
- goto failure; /* GCD not 1 */
-
- /* t1 += q * t0; */
- assert(plen+t0len <= mlen+1);
- lbnMul_16(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
- plen = lbnNorm_16(p, plen + t0len);
- assert(plen <= mlen);
- if (plen > t1len) {
- lbnZero_16(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
- t1len = plen;
- }
- cy = lbnAddN_16(t1, p, plen);
- if (cy) {
- if (t1len > plen) {
- cy = lbnAdd1_16(BIGLITTLE(t1-plen,t0+plen),
- t1len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
- t1len++;
- }
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
-
- if (!blen)
- goto failure; /* gcd(a, mod) != 1 -- FAIL */
-
- /* return mod-t1 */
- lbnCopy_16(a, mod, mlen);
- assert(t1len <= mlen);
- cy = lbnSubN_16(a, t1, t1len);
- if (cy) {
- assert(mlen > t1len);
- cy = lbnSub1_16(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
- assert(!cy);
- }
-
-success:
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return 0;
-
-failure: /* GCD is not 1 - no inverse exists! */
- y = 1;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod". Compute them every "bits"
- * for "n" steps. This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- *
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_16(BNWORD16 **array, unsigned n, unsigned bits,
- BNWORD16 const *g, unsigned glen, BNWORD16 *mod, unsigned mlen)
-{
- BNWORD16 *a, *b; /* Temporary double-width accumulators */
- BNWORD16 *a1; /* Pointer to high half of a*/
- BNWORD16 inv; /* Montgomery inverse of LSW of mod */
- BNWORD16 *t;
- unsigned i;
-
- glen = lbnNorm_16(g, glen);
- assert(glen);
-
- assert (mlen == lbnNorm_16(mod, mlen));
- assert (glen <= mlen);
-
- /* Allocate two temporary buffers, and the array slots */
- LBNALLOC(a, BNWORD16, mlen*2);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD16, mlen*2);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Okay, all ready */
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_16(inv);
- /* Move g up "mlen" words into a (clearing the low mlen words) */
- a1 = BIGLITTLE(a-mlen,a+mlen);
- lbnCopy_16(a1, g, glen);
- lbnZero_16(a, mlen);
-
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_16(a1, a, mlen+glen, mod, mlen);
-
- /* Copy the first value into the array */
- t = *array;
- lbnCopy_16(t, a, mlen);
- a1 = a; /* This first value is *not* shifted up */
-
- /* Now compute the remaining n-1 array entries */
- assert(bits);
- assert(n);
- while (--n) {
- i = bits;
- do {
- /* Square a1 into b1 */
- lbnMontSquare_16(b, a1, mod, mlen, inv);
- t = b; b = a; a = t;
- a1 = BIGLITTLE(a-mlen, a+mlen);
- } while (--i);
- t = *++array;
- lbnCopy_16(t, a1, mlen);
- }
-
- /* Hooray, we're done. */
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return 0;
-}
-
-/*
- * result = base^exp (mod mod). "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart. (I.e. array[i]
- * is base^(2^(i*bits))).
- *
- * The algorithm consists of:
- * a = b = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_16(BNWORD16 *result, BNWORD16 const * const *array,
- unsigned bits, BNWORD16 const *exp, unsigned elen,
- BNWORD16 const *mod, unsigned mlen)
-{
- BNWORD16 *a, *b, *c, *t;
- BNWORD16 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD16 const *eptr; /* Pointer into exp */
- BNWORD16 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD16 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
-
- mlen = lbnNorm_16(mod, mlen);
- assert (mlen);
-
- elen = lbnNorm_16(exp, elen);
- if (!elen) {
- lbnZero_16(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD16, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD16, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD16, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Set up bit buffer for walking the exponent */
- eptr = exp;
- buf = BIGLITTLE(*--eptr, *eptr++);
- ewords = elen-1;
- bufbits = 16;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 16;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD16 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_16(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_16(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_16(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_16(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_16(a, a1, mlen);
- lbnZero_16(a1, mlen);
- lbnMontReduce_16(a, mod, mlen, inv);
- lbnCopy_16(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod). "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart. (I.e. array1[i] is base1^(2^(i*bits))).
- *
- * Bits must be the same in both. (It could be made adjustable, but it's
- * a bit of a pain. Just make them both equal to the larger one.)
- *
- * The algorithm consists of:
- * a = b = (powers of base1 and base2 to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_16(BNWORD16 *result, unsigned bits,
- BNWORD16 const * const *array1, BNWORD16 const *exp1, unsigned elen1,
- BNWORD16 const * const *array2, BNWORD16 const *exp2,
- unsigned elen2, BNWORD16 const *mod, unsigned mlen)
-{
- BNWORD16 *a, *b, *c, *t;
- BNWORD16 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j, k; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD16 const *eptr; /* Pointer into exp */
- BNWORD16 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD16 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
- BNWORD16 const * const *array;
-
- mlen = lbnNorm_16(mod, mlen);
- assert (mlen);
-
- elen1 = lbnNorm_16(exp1, elen1);
- if (!elen1) {
- return lbnBasePrecompExp_16(result, array2, bits, exp2, elen2,
- mod, mlen);
- }
- elen2 = lbnNorm_16(exp2, elen2);
- if (!elen2) {
- return lbnBasePrecompExp_16(result, array1, bits, exp1, elen1,
- mod, mlen);
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen1);
- assert(elen2);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD16, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD16, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD16, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Walk each exponent in turn */
- for (k = 0; k < 2; k++) {
- /* Set up the exponent for walking */
- array = k ? array2 : array1;
- eptr = k ? exp2 : exp1;
- ewords = (k ? elen2 : elen1) - 1;
- /* Set up bit buffer for walking the exponent */
- buf = BIGLITTLE(*--eptr, *eptr++);
- bufbits = 16;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 16;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD16 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_16(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_16(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_16(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_16(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_16(a, a1, mlen);
- lbnZero_16(a1, mlen);
- lbnMontReduce_16(a, mod, mlen, inv);
- lbnCopy_16(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn16.h b/jni/libzrtp/sources/bnlib/lbn16.h
deleted file mode 100644
index f2237ce..0000000
--- a/jni/libzrtp/sources/bnlib/lbn16.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN16_H
-#define LBN16_H
-
-#include "lbn.h"
-
-#ifndef BNWORD16
-#error 16-bit bignum library requires a 16-bit data type
-#endif
-
-#ifndef lbnCopy_16
-void lbnCopy_16(BNWORD16 *dest, BNWORD16 const *src, unsigned len);
-#endif
-#ifndef lbnZero_16
-void lbnZero_16(BNWORD16 *num, unsigned len);
-#endif
-#ifndef lbnNeg_16
-void lbnNeg_16(BNWORD16 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_16
-BNWORD16 lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry);
-#endif
-#ifndef lbnSub1_16
-BNWORD16 lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow);
-#endif
-
-#ifndef lbnAddN_16
-BNWORD16 lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_16
-BNWORD16 lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_16
-int lbnCmp_16(BNWORD16 const *num1, BNWORD16 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_16
-void lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-#ifndef lbnMulAdd1_16
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-#ifndef lbnMulSub1_16
-BNWORD16 lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-
-#ifndef lbnLshift_16
-BNWORD16 lbnLshift_16(BNWORD16 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_16
-BNWORD16 lbnDouble_16(BNWORD16 *num, unsigned len);
-#endif
-#ifndef lbnRshift_16
-BNWORD16 lbnRshift_16(BNWORD16 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_16
-void lbnMul_16(BNWORD16 *prod, BNWORD16 const *num1, unsigned len1,
- BNWORD16 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_16
-void lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_16
-unsigned lbnNorm_16(BNWORD16 const *num, unsigned len);
-#endif
-#ifndef lbnBits_16
-unsigned lbnBits_16(BNWORD16 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_16
-void lbnExtractBigBytes_16(BNWORD16 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_16
-void lbnInsertBigBytes_16(BNWORD16 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_16
-void lbnExtractLittleBytes_16(BNWORD16 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_16
-void lbnInsertLittleBytes_16(BNWORD16 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_16
-BNWORD16 lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d);
-#endif
-#ifndef lbnDiv1_16
-BNWORD16 lbnDiv1_16(BNWORD16 *q, BNWORD16 *rem,
- BNWORD16 const *n, unsigned len, BNWORD16 d);
-#endif
-#ifndef lbnModQ_16
-unsigned lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_16
-BNWORD16
-lbnDiv_16(BNWORD16 *q, BNWORD16 *n, unsigned nlen, BNWORD16 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_16
-BNWORD16 lbnMontInv1_16(BNWORD16 const x);
-#endif
-#ifndef lbnMontReduce_16
-void lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned const mlen,
- BNWORD16 inv);
-#endif
-#ifndef lbnToMont_16
-void lbnToMont_16(BNWORD16 *n, unsigned nlen, BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_16
-void lbnFromMont_16(BNWORD16 *n, BNWORD16 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_16
-int lbnExpMod_16(BNWORD16 *result, BNWORD16 const *n, unsigned nlen,
- BNWORD16 const *exp, unsigned elen, BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_16
-int lbnDoubleExpMod_16(BNWORD16 *result,
- BNWORD16 const *n1, unsigned n1len, BNWORD16 const *e1, unsigned e1len,
- BNWORD16 const *n2, unsigned n2len, BNWORD16 const *e2, unsigned e2len,
- BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_16
-int lbnTwoExpMod_16(BNWORD16 *n, BNWORD16 const *exp, unsigned elen,
- BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_16
-int lbnGcd_16(BNWORD16 *a, unsigned alen, BNWORD16 *b, unsigned blen,
- unsigned *rlen);
-#endif
-#ifndef lbnInv_16
-int lbnInv_16(BNWORD16 *a, unsigned alen, BNWORD16 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_16(BNWORD16 **array, unsigned n, unsigned bits,
- BNWORD16 const *g, unsigned glen, BNWORD16 *mod, unsigned mlen);
-int lbnBasePrecompExp_16(BNWORD16 *result, BNWORD16 const * const *array,
- unsigned bits, BNWORD16 const *exp, unsigned elen,
- BNWORD16 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_16(BNWORD16 *result, unsigned bits,
- BNWORD16 const * const *array1, BNWORD16 const *exp1, unsigned elen1,
- BNWORD16 const * const *array2, BNWORD16 const *exp2,
- unsigned elen2, BNWORD16 const *mod, unsigned mlen);
-
-#endif /* LBN16_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn32.c b/jni/libzrtp/sources/bnlib/lbn32.c
deleted file mode 100644
index 73fedcb..0000000
--- a/jni/libzrtp/sources/bnlib/lbn32.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn32.c - Low-level bignum routines, 32-bit version.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "32" and "64" appear in many places in this
- * file, including inside identifiers. Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly. Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions. Any reference to the number of bits
- * in a word must be the string "32", and that string must not appear
- * otherwise. Any reference to twice this number must appear as "64",
- * which likewise must not appear otherwise. Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (64)
- * first, then the smaller (32). When halving the bit size, do the
- * opposite. Otherwise, things will get wierd. Also, be sure to replace
- * every instance that appears. (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD32s. The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way. If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END. The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1]. This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative. The expression used in this
- * code, *(ptr-i) will, however, work. (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this. An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names. If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made. Use the BNINCLUDE file to do that. Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_32 lbnMulAdd1_32
- *
- * If you want to write asm routines, start with lbnMulAdd1_32().
- * This is the workhorse of modular exponentiation. lbnMulN1_32() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_32 if that has a custom version. lbnMulSub1_32 and
- * lbnDiv21_32 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_32 defined, writing the other two should
- * be pretty easy. (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_32 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD64)
- * type are lbnMulAdd1_32 and lbnMulSub1_32; if those are provided,
- * the rest follows. lbnDiv21_32, however, is a lot slower unless you
- * have them, and lbnModQ_32 takes after it. That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn32.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD32
-#error 32-bit bignum library requires a 32-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void); /* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach. One big advantage of this is that the assembly
- * support routines are simpler. The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach. This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster. Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default. Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries. I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words. <Marvin mode on> Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD32)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_32
-void
-lbnCopy_32(BNWORD32 *dest, BNWORD32 const *src, unsigned len)
-{
- memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
- len * sizeof(*src));
-}
-#endif /* !lbnCopy_32 */
-
-/*
- * Fill n words with zero. This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't. Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_32
-void
-lbnZero_32(BNWORD32 *num, unsigned len)
-{
- while (len--)
- BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_32 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero. Negating low-order words
- * entails doing nothing until a non-zero word is hit. Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit. Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_32
-void
-lbnNeg_32(BNWORD32 *num, unsigned len)
-{
- assert(len);
-
- /* Skip low-order zero words */
- while (BIGLITTLE(*--num,*num) == 0) {
- if (!--len)
- return;
- LITTLE(num++;)
- }
- /* Negate the lowest-order non-zero word */
- *num = -*num;
- /* Complement all the higher-order words */
- while (--len) {
- BIGLITTLE(--num,++num);
- *num = ~*num;
- }
-}
-#endif /* !lbnNeg_32 */
-
-
-/*
- * lbnAdd1_32: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex. After adding the first carry, which may
- * be > 1, compare the sum and the carry. If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^32) which is larger than
- * the other input can possibly be. If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap. Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_32 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD64
-BNWORD32
-lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
-{
- BNWORD64 t;
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- t = (BNWORD64)BIGLITTLE(*--num,*num) + carry;
- BIGLITTLE(*num,*num++) = (BNWORD32)t;
- if ((t >> 32) == 0)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
-{
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif/* !lbnAdd1_32 */
-
-/*
- * lbnSub1_32: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above. If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry. If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow. If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0. To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD32). If the size of an int is larger
- * than BNWORD32, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_32 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD64
-BNWORD32
-lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
-{
- BNWORD64 t;
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- t = (BNWORD64)BIGLITTLE(*--num,*num) - borrow;
- BIGLITTLE(*num,*num++) = (BNWORD32)t;
- if ((t >> 32) == 0)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
-{
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD32)~borrow)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif /* !lbnSub1_32 */
-
-/*
- * lbnAddN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry. If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs. Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true. The first can
- * only be true if carry == 1 and x, the result, is 0. In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_32
-#ifdef BNWORD64
-BNWORD32
-lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
- BNWORD64 t;
-
- assert(len > 0);
-
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- while (--len) {
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) +
- (BNWORD64)BIGLITTLE(*--num2,*num2++) + (t >> 32);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- }
-
- return (BNWORD32)(t>>32);
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
- BNWORD32 x, carry = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- carry = (x += carry) < carry;
- carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
- } while (--len);
-
- return carry;
-}
-#endif
-#endif /* !lbnAddN_32 */
-
-/*
- * lbnSubN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again. Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true. The first can only be true if
- * borrow == 1 and x, the result, is 0. In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD32)-(t>>32) is subtracted, rather than
- * adding t>>32, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_32
-#ifdef BNWORD64
-BNWORD32
-lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
- BNWORD64 t;
-
- assert(len > 0);
-
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
-
- while (--len) {
- t = (BNWORD64)BIGLITTLE(*--num1,*num1) -
- (BNWORD64)BIGLITTLE(*--num2,*num2++) - (BNWORD32)-(t >> 32);
- BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
- }
-
- return -(BNWORD32)(t>>32);
-}
-#else
-BNWORD32
-lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
- BNWORD32 x, borrow = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- borrow = (x += borrow) < borrow;
- borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD32)~x;
- } while (--len);
-
- return borrow;
-}
-#endif
-#endif /* !lbnSubN_32 */
-
-#ifndef lbnCmp_32
-/*
- * lbnCmp_32: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- *
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_32(BNWORD32 const *num1, BNWORD32 const *num2, unsigned len)
-{
- BIGLITTLE(num1 -= len, num1 += len);
- BIGLITTLE(num2 -= len, num2 += len);
-
- while (len--) {
- if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
- if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
- return -1;
- else
- return 1;
- }
- }
- return 0;
-}
-#endif /* !lbnCmp_32 */
-
-/*
- * mul32_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b. mul32_ppmma and mul32_ppmm
- * are simpler versions. If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul32_ppmma) && defined(mul32_ppmmaa)
-#define mul32_ppmma(ph,pl,x,y,a) mul32_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul32_ppmm) && defined(mul32_ppmma)
-#define mul32_ppmm(ph,pl,x,y) mul32_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul32_ppmm-based operations on machines
- * that do not provide mul32_ppmm. Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul32_ppmm) && defined(BNWORD64) && 0 /* Debugging */
-#define mul32_ppmm(ph,pl,x,y) \
- ({BNWORD64 _ = (BNWORD64)(x)*(y); (pl) = _; (ph) = _>>32;})
-#endif
-
-#if defined(mul32_ppmm) && !defined(mul32_ppmma)
-#define mul32_ppmma(ph,pl,x,y,a) \
- (mul32_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul32_ppmma) && !defined(mul32_ppmmaa)
-#define mul32_ppmmaa(ph,pl,x,y,a,b) \
- (mul32_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_32: Multiply an n-word input by a 1-word input and store the
- * n+1-word product. This uses either the mul32_ppmm and mul32_ppmma
- * macros, or C multiplication with the BNWORD64 type. This uses mul32_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_32
-#ifdef lbnMulAdd1_32 /* If we have this asm primitive, use it. */
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- lbnZero_32(out, len);
- BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_32(out, in, len, k);
-}
-#elif defined(mul32_ppmm)
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD32 carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- mul32_ppmm(carry, *out, *in, k);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;)
- carryin = carry;
- mul32_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
- }
- BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD64)
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD64 p;
-
- assert(len > 0);
-
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
- BIGLITTLE(*--out,*out++) = (BNWORD32)p;
-
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + (BNWORD32)(p >> 32);
- BIGLITTLE(*--out,*out++) = (BNWORD32)p;
- }
- BIGLITTLE(*--out,*out) = (BNWORD32)(p >> 32);
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* lbnMulN1_32 */
-
-/*
- * lbnMulAdd1_32: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination. *Returns the n+1st word
- * of the product.* (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.) This uses either the mul32_ppmma and mul32_ppmmaa macros,
- * or C multiplication with the BNWORD64 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with. It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_32
-#if defined(mul32_ppmm)
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD32 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- carryin = *out;
- mul32_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;);
- carryin = carry;
- mul32_ppmmaa(carry, prod, *in, k, carryin, *out);
- *out = prod;
- LITTLE(out++;in++;)
- }
-
- return carry;
-}
-#elif defined(BNWORD64)
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD64 p;
-
- assert(len > 0);
-
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD32)p;
-
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k +
- (BNWORD32)(p >> 32) + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD32)p;
- }
-
- return (BNWORD32)(p >> 32);
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* lbnMulAdd1_32 */
-
-/*
- * lbnMulSub1_32: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination. Returns the n+1st word of the product.
- * This uses either the mul32_ppmm and mul32_ppmma macros, or
- * C multiplication with the BNWORD64 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_32
-#if defined(mul32_ppmm)
-BNWORD32
-lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD32 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--in;)
- mul32_ppmm(carry, prod, *in, k);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
-
- while (--len) {
- BIG(--in;);
- carryin = carry;
- mul32_ppmma(carry, prod, *in, k, carryin);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
- }
-
- return carry;
-}
-#elif defined(BNWORD64)
-BNWORD32
-lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
- BNWORD64 p;
- BNWORD32 carry, t;
-
- assert(len > 0);
-
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD32)(p>>32) + ((BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t);
-
- while (--len) {
- p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + carry;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD32)(p>>32) +
- ( (BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t );
- }
-
- return carry;
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* !lbnMulSub1_32 */
-
-/*
- * Shift n words left "shift" bits. 0 < shift < 32. Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_32
-BNWORD32
-lbnLshift_32(BNWORD32 *num, unsigned len, unsigned shift)
-{
- BNWORD32 x, carry;
-
- assert(shift > 0);
- assert(shift < 32);
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<shift) | carry;
- LITTLE(num++;)
- carry = x >> (32-shift);
- }
- return carry;
-}
-#endif /* !lbnLshift_32 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_32
-BNWORD32
-lbnDouble_32(BNWORD32 *num, unsigned len)
-{
- BNWORD32 x, carry;
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<1) | carry;
- LITTLE(num++;)
- carry = x >> (32-1);
- }
- return carry;
-}
-#endif /* !lbnDouble_32 */
-
-/*
- * Shift n words right "shift" bits. 0 < shift < 32. Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_32
-BNWORD32
-lbnRshift_32(BNWORD32 *num, unsigned len, unsigned shift)
-{
- BNWORD32 x, carry = 0;
-
- assert(shift > 0);
- assert(shift < 32);
-
- BIGLITTLE(num -= len, num += len);
-
- while (len--) {
- LITTLE(--num;)
- x = *num;
- *num = (x>>shift) | carry;
- BIG(num++;)
- carry = x << (32-shift);
- }
- return carry >> (32-shift);
-}
-#endif /* !lbnRshift_32 */
-
-/*
- * Multiply two numbers of the given lengths. prod and num2 may overlap,
- * provided that the low len1 bits of prod are free. (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_32.)
- *
- * TODO: Use Karatsuba multiply. The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_32
-void
-lbnMul_32(BNWORD32 *prod, BNWORD32 const *num1, unsigned len1,
- BNWORD32 const *num2, unsigned len2)
-{
- /* Special case of zero */
- if (!len1 || !len2) {
- lbnZero_32(prod, len1+len2);
- return;
- }
-
- /* Multiply first word */
- lbnMulN1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
- /*
- * Add in subsequent words, storing the most significant word,
- * which is new each time.
- */
- while (--len2) {
- BIGLITTLE(--prod,prod++);
- BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
- lbnMulAdd1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
- }
-}
-#endif /* !lbnMul_32 */
-
-/*
- * lbnMulX_32 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_32
-#if defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster. It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
- unsigned len)
-{
- BNWORD64 x, y;
- BNWORD32 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
- x >>= 32;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- for (j = 0; j <= i; j++) {
- BIG(y = (BNWORD64)*--p1 * *p2++;)
- LITTLE(y = (BNWORD64)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- for (j = i; j < len; j++) {
- BIG(y = (BNWORD64)*--p1 * *p2++;)
- LITTLE(y = (BNWORD64)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
-}
-#else /* !defined(BNWORD64) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_32(prod, num1, num2, len) lbnMul_32(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD64) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_32 */
-
-#if !defined(lbnMontMul_32) && defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply. This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops. The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers. These are stored in the product array,
- * which contains no data as of yet. x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
- BNWORD32 const *mod, unsigned len, BNWORD32 inv)
-{
- BNWORD64 x, y;
- BNWORD32 const *p1, *p2, *pm;
- BNWORD32 *pp;
- BNWORD32 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /*
- * This computes directly into the high half of prod, so just
- * shift the pointer and consider prod only "len" elements long
- * for the rest of the code.
- */
- BIGLITTLE(prod -= len, prod += len);
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD32)x;
- y = (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]);
- x += y;
- /* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
- carry = (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- pp = prod;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD64)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
- x += y;
- carry += (x < y);
- }
- y = (BNWORD64)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
- x += y;
- carry += (x < y);
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD32)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
- }
-
- /* Pass 2 - compute reduced product and store */
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- pm = BIGLITTLE(mod-i,mod+i);
- pp = BIGLITTLE(prod-len,prod+len);
- for (j = i; j < len; j++) {
- y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD64)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-len, pm == mod+len));
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[0],pp[-1]) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- /* Last round of second half, simplified. */
- BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD32)x;
- carry = (x >> 32);
-
- while (carry)
- carry -= lbnSubN_32(prod, mod, len);
- while (lbnCmp_32(prod, mod, len) >= 0)
- (void)lbnSubN_32(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_32 lbnMontMul_32
-#endif
-
-#if !defined(lbnSquare_32) && defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring. This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
-{
- BNWORD64 x, y, z;
- BNWORD32 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /* Word 0 of product */
- x = (BNWORD64)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
- x >>= 32;
-
- /* Words 1 through len-1 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = num;
- p2 = BIGLITTLE(num-i-1,num+i+1);
- for (j = 0; j < (i+1)/2; j++) {
- BIG(z = (BNWORD64)*--p1 * *p2++;)
- LITTLE(z = (BNWORD64)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((i & 1) == 0) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD64)*p2 * *p2;)
- LITTLE(z = (BNWORD64)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
- /* Words len through 2*len-2 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = BIGLITTLE(num-i,num+i);
- p2 = BIGLITTLE(num-len,num+len);
- for (j = 0; j < (len-i)/2; j++) {
- BIG(z = (BNWORD64)*--p1 * *p2++;)
- LITTLE(z = (BNWORD64)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((len-i) & 1) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD64)*p2 * *p2;)
- LITTLE(z = (BNWORD64)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- /* Word 2*len-1 */
- BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
-}
-/* Suppress later definition */
-#define lbnSquare_32 lbnSquare_32
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed. There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- * a b c d e
- * * a b c d e
- * ==================
- * ae be ce de ee
- * ad bd cd dd de
- * ac bc cc cd ce
- * ab bb bc bd be
- * aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- * ae be ce de = (abcd) * e
- * ad bd cd = (abc) * d
- * ac bc = (ab) * c
- * ab = (a) * b
- *
- * is a copy of everything below the main diagonal:
- * de
- * cd ce
- * bc bd be
- * ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again. The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba. (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_32
-void
-lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
-{
- BNWORD32 t;
- BNWORD32 *prodx = prod; /* Working copy of the argument */
- BNWORD32 const *numx = num; /* Working copy of the argument */
- unsigned lenx = len; /* Working copy of the argument */
-
- if (!len)
- return;
-
- /* First, store all the squares */
- while (lenx--) {
-#ifdef mul32_ppmm
- BNWORD32 ph, pl;
- t = BIGLITTLE(*--numx,*numx++);
- mul32_ppmm(ph,pl,t,t);
- BIGLITTLE(*--prodx,*prodx++) = pl;
- BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD64) /* use BNWORD64 */
- BNWORD64 p;
- t = BIGLITTLE(*--numx,*numx++);
- p = (BNWORD64)t * t;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)p;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)(p>>32);
-#else /* Use lbnMulN1_32 */
- t = BIGLITTLE(numx[-1],*numx);
- lbnMulN1_32(prodx, numx, 1, t);
- BIGLITTLE(--numx,numx++);
- BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
- }
- /* Then, shift right 1 bit */
- (void)lbnRshift_32(prod, 2*len, 1);
-
- /* Then, add in the off-diagonal sums */
- lenx = len;
- numx = num;
- prodx = prod;
- while (--lenx) {
- t = BIGLITTLE(*--numx,*numx++);
- BIGLITTLE(--prodx,prodx++);
- t = lbnMulAdd1_32(prodx, numx, lenx, t);
- lbnAdd1_32(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
- BIGLITTLE(--prodx,prodx++);
- }
-
- /* Shift it back up */
- lbnDouble_32(prod, 2*len);
-
- /* And set the low bit appropriately */
- BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_32 */
-
-/*
- * lbnNorm_32 - given a number, return a modified length such that the
- * most significant digit is non-zero. Zero-length input is okay.
- */
-#ifndef lbnNorm_32
-unsigned
-lbnNorm_32(BNWORD32 const *num, unsigned len)
-{
- BIGLITTLE(num -= len,num += len);
- while (len && BIGLITTLE(*num++,*--num) == 0)
- --len;
- return len;
-}
-#endif /* lbnNorm_32 */
-
-/*
- * lbnBits_32 - return the number of significant bits in the array.
- * It starts by normalizing the array. Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 32, and
- * subtracts off 32/2, 32/4, 32/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_32
-unsigned
-lbnBits_32(BNWORD32 const *num, unsigned len)
-{
- BNWORD32 t;
- unsigned i;
-
- len = lbnNorm_32(num, len);
- if (len) {
- t = BIGLITTLE(*(num-len),*(num+(len-1)));
- assert(t);
- len *= 32;
- i = 32/2;
- do {
- if (t >> i)
- t >>= i;
- else
- len -= i;
- } while ((i /= 2) != 0);
- }
- return len;
-}
-#endif /* lbnBits_32 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 32 bits, which a general 64-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_64
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_64 (64 > 0x20)
-#endif
-
-/*
- * Return (nh<<32|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set). If we have a double-width type, it's easy. If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_32
-#if defined(BNWORD64) && !BN_SLOW_DIVIDE_64
-BNWORD32
-lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
-{
- BNWORD64 n = (BNWORD64)nh << 32 | nl;
-
- /* Divisor must be normalized */
- assert(d >> (32-1) == 1);
-
- *q = n / d;
- return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth. Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- * _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- * - (qh * d)
- * -----------
- * rrrr rrrr nl.l
- * - (ql * d)
- * -----------
- * rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- * First, estimate a q digit so that nh/dh works. Subtracting qh*dh from
- * the (nh.h nh.l) list leaves a 1/2-word remainder r. Then compute the
- * low part of the subtractor, qh * dl. This also needs to be subtracted
- * from (nh.h nh.l nl.h) to get the final remainder. So we take the
- * remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- * try to subtract qh * dl from that. Since the remainder is 1/2-word
- * long, shifting and adding nl.h results in a single word r.
- * It is possible that the remainder we're working with, r, is less than
- * the product qh * dl, if we estimated qh too high. The estimation
- * technique can produce a qh that is too large (never too small), leading
- * to r which is too small. In that case, decrement the digit qh, add
- * shifted dh to r (to correct for that error), and subtract dl from the
- * product we're comparing r with. That's the "correct" way to do it, but
- * just adding dl to r instead of subtracting it from the product is
- * equivalent and a lot simpler. You just have to watch out for overflow.
- *
- * The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- * quotient ql.
- *
- * The various uses of 32/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 32/2 )
-#define lowhalf(x) ( (x) & (((BNWORD32)1 << 32/2)-1) )
-BNWORD32
-lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
-{
- BNWORD32 dh = highhalf(d), dl = lowhalf(d);
- BNWORD32 qh, ql, prod, r;
-
- /* Divisor must be normalized */
- assert((d >> (32-1)) == 1);
-
- /* Do first half-word of division */
- qh = nh / dh;
- r = nh % dh;
- prod = qh * dl;
-
- /*
- * Add next half-word of numerator to remainder and correct.
- * qh may be up to two too large.
- */
- r = (r << (32/2)) | highhalf(nl);
- if (r < prod) {
- --qh; r += d;
- if (r >= d && r < prod) {
- --qh; r += d;
- }
- }
- r -= prod;
-
- /* Do second half-word of division */
- ql = r / dh;
- r = r % dh;
- prod = ql * dl;
-
- r = (r << (32/2)) | lowhalf(nl);
- if (r < prod) {
- --ql; r += d;
- if (r >= d && r < prod) {
- --ql; r += d;
- }
- }
- r -= prod;
-
- *q = (qh << (32/2)) | ql;
-
- return r;
-}
-#endif
-#endif /* lbnDiv21_32 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long. It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient. The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_64, add a divnhalf_32 which uses 32-bit
- * dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- * instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_32
-BNWORD32
-lbnDiv1_32(BNWORD32 *q, BNWORD32 *rem, BNWORD32 const *n, unsigned len,
- BNWORD32 d)
-{
- unsigned shift;
- unsigned xlen;
- BNWORD32 r;
- BNWORD32 qhigh;
-
- assert(len > 0);
- assert(d);
-
- if (len == 1) {
- r = *n;
- *rem = r%d;
- return r/d;
- }
-
- shift = 0;
- r = d;
- xlen = 32/2;
- do {
- if (r >> xlen)
- r >>= xlen;
- else
- shift += xlen;
- } while ((xlen /= 2) != 0);
- assert((d >> (32-1-shift)) == 1);
- d <<= shift;
-
- BIGLITTLE(q -= len-1,q += len-1);
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r < d) {
- qhigh = 0;
- } else {
- qhigh = r/d;
- r %= d;
- }
-
- xlen = len;
- while (--xlen)
- r = lbnDiv21_32(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift) {
- d >>= shift;
- qhigh = (qhigh << shift) | lbnLshift_32(q, len-1, shift);
- BIGLITTLE(q[-1],*q) |= r/d;
- r %= d;
- }
- *rem = r;
-
- return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_32
-/* If there's a custom lbnMod21_32, no normalization needed */
-#ifdef lbnMod21_32
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD32 r;
-
- assert(len > 0);
-
- BIGLITTLE(n -= len,n += len);
-
- /* Try using a compare to avoid the first divide */
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
- while (--len)
- r = lbnMod21_32(r, BIGLITTLE(*n++,*--n), d);
-
- return r;
-}
-#elif defined(BNWORD64) && !BN_SLOW_DIVIDE_64
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
- BNWORD32 r;
-
- if (!--len)
- return BIGLITTLE(n[-1],n[0]) % d;
-
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(n[-1],n[0]);
-
- do {
- r = (BNWORD32)((((BNWORD64)r<<32) | BIGLITTLE(*n++,*--n)) % d);
- } while (--len);
-
- return r;
-}
-#elif 32 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 32/2 )
-#define lowhalf(x) ( (x) & ((1 << 32/2)-1) )
-#endif
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
- BNWORD32 r, x;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- while (--len) {
- x = BIGLITTLE(*n++,*--n);
- r = (r%d << 32/2) | highhalf(x);
- r = (r%d << 32/2) | lowhalf(x);
- }
-
- return r%d;
-}
-#else
-/* Default case - use lbnDiv21_32 */
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD32 r;
- BNWORD32 q;
-
- assert(len > 0);
-
- shift = 0;
- r = d;
- i = 32;
- while (i /= 2) {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- }
- assert(d >> (32-1-shift) == 1);
- d <<= shift;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
-
- while (--len)
- r = lbnDiv21_32(&q, r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift)
- r %= d >> shift;
-
- return r;
-}
-#endif
-#endif /* lbnModQ_32 */
-
-/*
- * Reduce n mod d and return the quotient. That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long. To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor. WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction. This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount. This will produce the
- * correct quotient, and the remainder can be recovered by shifting
- * it back down the same number of bits. This may produce an overflow
- * word, but the word is always strictly less than the most significant
- * divisor word.
- * - Estimate the first quotient digit qhat:
- * - First take the top two words (one of which is the overflow) of the
- * dividend and divide by the top word of the divisor:
- * qhat = (nh,nm)/dh. This qhat is >= the correct quotient digit
- * and, since dh is normalized, it is at most two over.
- * - Second, correct by comparing the top three words. If
- * (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- * The second iteration can be simpler because there can't be a third.
- * The computation can be simplified by subtracting dh*qhat from
- * both sides, suitably shifted. This reduces the left side to
- * dl*qhat. On the right, (nh,nm)-dh*qhat is simply the
- * remainder r from (nh,nm)%dh, so the right is (r,nl).
- * This produces qhat that is almost always correct and at
- * most (prob ~ 2/2^32) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- * If there is a borrow, qhat was wrong, so decrement it
- * and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed. Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_32
-BNWORD32
-lbnDiv_32(BNWORD32 *q, BNWORD32 *n, unsigned nlen, BNWORD32 *d, unsigned dlen)
-{
- BNWORD32 nh,nm,nl; /* Top three words of the dividend */
- BNWORD32 dh,dl; /* Top two words of the divisor */
- BNWORD32 qhat; /* Extimate of quotient word */
- BNWORD32 r; /* Remainder from quotient estimate division */
- BNWORD32 qhigh; /* High word of quotient */
- unsigned i; /* Temp */
- unsigned shift; /* Bits shifted by normalization */
- unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul32_ppmm
- BNWORD32 t32;
-#elif defined(BNWORD64)
- BNWORD64 t64;
-#else /* use lbnMulN1_32 */
- BNWORD32 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
- assert(dlen);
- assert(nlen >= dlen);
-
- /*
- * Special cases for short divisors. The general case uses the
- * top top 2 digits of the divisor (d) to estimate a quotient digit,
- * so it breaks if there are fewer digits available. Thus, we need
- * special cases for a divisor of length 1. A divisor of length
- * 2 can have a *lot* of administrivia overhead removed removed,
- * so it's probably worth special-casing that case, too.
- */
- if (dlen == 1)
- return lbnDiv1_32(q, BIGLITTLE(n-1,n), n, nlen,
- BIGLITTLE(d[-1],d[0]));
-
-#if 0
- /*
- * @@@ This is not yet written... The general loop will do,
- * albeit less efficiently
- */
- if (dlen == 2) {
- /*
- * divisor two digits long:
- * use the 3/2 technique from Knuth, but we know
- * it's exact.
- */
- dh = BIGLITTLE(d[-1],d[0]);
- dl = BIGLITTLE(d[-2],d[1]);
- shift = 0;
- if ((sh & ((BNWORD32)1 << 32-1-shift)) == 0) {
- do {
- shift++;
- } while (dh & (BNWORD32)1<<32-1-shift) == 0);
- dh = dh << shift | dl >> (32-shift);
- dl <<= shift;
-
-
- }
-
-
- for (shift = 0; (dh & (BNWORD32)1 << 32-1-shift)) == 0; shift++)
- ;
- if (shift) {
- }
- dh = dh << shift | dl >> (32-shift);
- shift = 0;
- while (dh
- }
-#endif
-
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- assert(dh);
-
- /* Normalize the divisor */
- shift = 0;
- r = dh;
- i = 32/2;
- do {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- } while ((i /= 2) != 0);
-
- nh = 0;
- if (shift) {
- lbnLshift_32(d, dlen, shift);
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- nh = lbnLshift_32(n, nlen, shift);
- }
-
- /* Assert that dh is now normalized */
- assert(dh >> (32-1));
-
- /* Also get the second-most significant word of the divisor */
- dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
- /*
- * Adjust pointers: n to point to least significant end of first
- * first subtract, and q to one the most-significant end of the
- * quotient array.
- */
- BIGLITTLE(n -= qlen,n += qlen);
- BIGLITTLE(q -= qlen,q += qlen);
-
- /* Fetch the most significant stored word of the dividend */
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- /*
- * Compute the first digit of the quotient, based on the
- * first two words of the dividend (the most significant of which
- * is the overflow word h).
- */
- if (nh) {
- assert(nh < dh);
- r = lbnDiv21_32(&qhat, nh, nm, dh);
- } else if (nm >= dh) {
- qhat = nm/dh;
- r = nm % dh;
- } else { /* Quotient is zero */
- qhigh = 0;
- goto divloop;
- }
-
- /* Now get the third most significant word of the dividend */
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
- /*
- * Correct qhat, the estimate of quotient digit.
- * qhat can only be high, and at most two words high,
- * so the loop can be unrolled and abbreviated.
- */
-#ifdef mul32_ppmm
- mul32_ppmm(nm, t32, qhat, dl);
- if (nm > r || (nm == r && t32 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t32 < dl);
- t32 -= dl;
- if (nm > r || (nm == r && t32 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD64)
- t64 = (BNWORD64)qhat * dl;
- if (t64 > ((BNWORD64)r << 32) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) > dh) {
- t64 -= dl;
- if (t64 > ((BNWORD64)r << 32) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_32 */
- lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /* Do the multiply and subtract */
- r = lbnMulSub1_32(n, d, dlen, qhat);
- /* If there was a borrow, add back once. */
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_32(n, d, dlen);
- qhat--;
- }
-
- /* Remember the first quotient digit. */
- qhigh = qhat;
-
- /* Now, the main division loop: */
-divloop:
- while (qlen--) {
-
- /* Advance n */
- nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- BIGLITTLE(++n,--n);
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- if (nh == dh) {
- qhat = ~(BNWORD32)0;
- /* Optimized computation of r = (nh,nm) - qhat * dh */
- r = nh + nm;
- if (r < nh)
- goto subtract;
- } else {
- assert(nh < dh);
- r = lbnDiv21_32(&qhat, nh, nm, dh);
- }
-
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul32_ppmm
- mul32_ppmm(nm, t32, qhat, dl);
- if (nm > r || (nm == r && t32 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t32 < dl);
- t32 -= dl;
- if (nm > r || (nm == r && t32 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD64)
- t64 = (BNWORD64)qhat * dl;
- if (t64 > ((BNWORD64)r<<32) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t64 -= dl;
- if (t64 > ((BNWORD64)r << 32) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_32 */
- lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /*
- * As a point of interest, note that it is not worth checking
- * for qhat of 0 or 1 and installing special-case code. These
- * occur with probability 2^-32, so spending 1 cycle to check
- * for them is only worth it if we save more than 2^15 cycles,
- * and a multiply-and-subtract for numbers in the 1024-bit
- * range just doesn't take that long.
- */
-subtract:
- /*
- * n points to the least significant end of the substring
- * of n to be subtracted from. qhat is either exact or
- * one too large. If the subtract gets a borrow, it was
- * one too large and the divisor is added back in. It's
- * a dlen+1 word add which is guaranteed to produce a
- * carry out, so it can be done very simply.
- */
- r = lbnMulSub1_32(n, d, dlen, qhat);
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_32(n, d, dlen);
- qhat--;
- }
- /* Store the quotient digit */
- BIGLITTLE(*q++,*--q) = qhat;
- }
- /* Tah dah! */
-
- if (shift) {
- lbnRshift_32(d, dlen, shift);
- lbnRshift_32(n, dlen, shift);
- }
-
- return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^32.
- *
- * This just performs Newton's iteration until it gets the
- * inverse. The initial estimate is always correct to 3 bits, and
- * sometimes 4. The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n. x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_32
-BNWORD32
-lbnMontInv1_32(BNWORD32 const x)
-{
- BNWORD32 y = x, z;
-
- assert(x & 1);
-
- while ((z = x*y) != 1)
- y *= 2 - z;
- return -y;
-}
-#endif /* !lbnMontInv1_32 */
-
-#if defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned mlen, BNWORD32 inv)
-{
- BNWORD64 x, y;
- BNWORD32 const *pm;
- BNWORD32 *pn;
- BNWORD32 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!mlen)
- return;
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- t = BIGLITTLE(n[-1],n[0]);
- x = t;
- t *= inv;
- BIGLITTLE(n[-1], n[0]) = t;
- x += (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
- assert((BNWORD32)x == 0);
- x = x >> 32;
-
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pn = n;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD64)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pn == n-i, pn == n+i));
- y = t = BIGLITTLE(pn[-1], pn[0]);
- x += y;
- carry += (x < y);
- BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD32)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD32)x == 0);
- x = x >> 32 | (BNWORD64)carry << 32;
- }
-
- BIGLITTLE(n -= mlen, n += mlen);
-
- /* Pass 2 - compute upper words and add to n */
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pm = BIGLITTLE(mod-i,mod+i);
- pn = n;
- for (j = i; j < mlen; j++) {
- y = (BNWORD64)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
- assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
- y = t = BIGLITTLE(*(n-i),*(n+i-1));
- x += y;
- carry += (x < y);
- BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD32)x;
- x = (x >> 32) | (BNWORD64)carry << 32;
- }
-
- /* Last round of second half, simplified. */
- t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
- x += t;
- BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD32)x;
- carry = (unsigned)(x >> 32);
-
- while (carry)
- carry -= lbnSubN_32(n, mod, mlen);
- while (lbnCmp_32(n, mod, mlen) >= 0)
- (void)lbnSubN_32(n, mod, mlen);
-}
-#define lbnMontReduce_32 lbnMontReduce_32
-#endif
-
-/*
- * Montgomery reduce n, modulo mod. This reduces modulo mod and divides by
- * 2^(32*mlen). Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_32.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction. What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift. In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(32*mlen). Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc. Note that:
- * - The Montgomery form of a number depends on the modulus m.
- * A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- * no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- * M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R. The problem
- * is to divide out the excess factor of R, modulo m as well as to
- * reduce to the given length mlen. It turns out that this can be
- * done *faster* than a normal divide, which is where the speedup
- * in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced. Choosing q is tricky
- * and involved (just look at lbnDiv_32 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced. This multiple is chosen to make the
- * low-order part of the number come out to zero. This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R. Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication. To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- *
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_32
-void
-lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned const mlen,
- BNWORD32 inv)
-{
- BNWORD32 t;
- BNWORD32 c = 0;
- unsigned len = mlen;
-
- /* inv must be the negative inverse of mod's least significant word */
- assert((BNWORD32)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD32)-1);
-
- assert(len);
-
- do {
- t = lbnMulAdd1_32(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
- c += lbnAdd1_32(BIGLITTLE(n-mlen,n+mlen), len, t);
- BIGLITTLE(--n,++n);
- } while (--len);
-
- /*
- * All that adding can cause an overflow past the modulus size,
- * but it's unusual, and never by much, so a subtraction loop
- * is the right way to deal with it.
- * This subtraction happens infrequently - I've only ever seen it
- * invoked once per reduction, and then just under 22.5% of the time.
- */
- while (c)
- c -= lbnSubN_32(n, mod, mlen);
- while (lbnCmp_32(n, mod, mlen) >= 0)
- (void)lbnSubN_32(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_32 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_32
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod". "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_32(prod, n1, n2, mod, len, inv) \
- (lbnMulX_32(prod, n1, n2, len), lbnMontReduce_32(prod, mod, len, inv))
-#endif /* !lbnMontMul_32 */
-
-#ifndef lbnMontSquare_32
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod". "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_32(prod, n, mod, len, inv) \
- (lbnSquare_32(prod, n, len), lbnMontReduce_32(prod, mod, len, inv))
-
-#endif /* !lbnMontSquare_32 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_32(BNWORD32 *n, unsigned nlen, BNWORD32 *mod, unsigned mlen)
-{
- /* Move n up "mlen" words */
- lbnCopy_32(BIGLITTLE(n-mlen,n+mlen), n, nlen);
- lbnZero_32(n, mlen);
- /* Do the division - dump the quotient in the high-order words */
- (void)lbnDiv_32(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form. Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_32(BNWORD32 *n, BNWORD32 *mod, unsigned len)
-{
- /* Zero the high words of n */
- lbnZero_32(BIGLITTLE(n-len,n+len), len);
- lbnMontReduce_32(n, mod, len, lbnMontInv1_32(mod[BIGLITTLE(-1,0)]));
- /* Move n down len words */
- lbnCopy_32(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k. See the comment in bnExpMod_32 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation. To minimize
- * the sum, k must vary with e. The optimal window sizes vary with the
- * exponent length. Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 32 do not appear in this table. It should be
- * ignored.)
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 8 bits, k=2 (3.333333) < k=1 (3.500000)
- * At e = 1_6 bits, k=2 (6.000000) is best
- * At e = 26 bits, k=3 (9.250000) < k=2 (9.333333)
- * At e = 3_2 bits, k=3 (10.750000) is best
- * At e = 6_4 bits, k=3 (18.750000) is best
- * At e = 82 bits, k=4 (23.200000) < k=3 (23.250000)
- * At e = 128 bits, k=4 (3_2.400000) is best
- * At e = 242 bits, k=5 (55.1_66667) < k=4 (55.200000)
- * At e = 256 bits, k=5 (57.500000) is best
- * At e = 512 bits, k=5 (100.1_66667) is best
- * At e = 674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation. The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2. For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5. Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings. It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case. Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all. Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 6 bits, k=2 (2.437500) < k=1 (2.500000)
- * At e = 8 bits, k=2 (3.109375) is best
- * At e = 1_6 bits, k=2 (5.777771) is best
- * At e = 24 bits, k=3 (8.437629) < k=2 (8.444444)
- * At e = 3_2 bits, k=3 (10.437492) is best
- * At e = 6_4 bits, k=3 (18.437500) is best
- * At e = 81 bits, k=4 (22.6_40000) < k=3 (22.687500)
- * At e = 128 bits, k=4 (3_2.040000) is best
- * At e = 241 bits, k=5 (54.611111) < k=4 (54.6_40000)
- * At e = 256 bits, k=5 (57.111111) is best
- * At e = 512 bits, k=5 (99.777778) is best
- * At e = 673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794. Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here. It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables. Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1. Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW 7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
- 5, 23, 80, 240, 672, 1792, (unsigned)-1
-/* 7, 25, 81, 241, 673, 1793, (unsigned)-1 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible! This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it. The following patterns
- * apply to a 3-bit window (k = 3):
- * To append 0: square
- * To append 1: square, multiply by n^1
- * To append 10: square, multiply by n^1, square
- * To append 11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time. Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes. There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits. (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it. We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away. Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings. 1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1. The average of these is 1. Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies. (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated. Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_32(BNWORD32 *result, BNWORD32 const *n, unsigned nlen,
- BNWORD32 const *e, unsigned elen, BNWORD32 *mod, unsigned mlen)
-{
- BNWORD32 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n */
- unsigned ebits; /* Exponent bits */
- unsigned wbits; /* Window size */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD32 bitpos; /* Mask of current look-ahead bit */
- unsigned buf; /* Buffer of exponent bits */
- unsigned multpos; /* Where to do pending multiply */
- BNWORD32 const *mult; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD32 *a, *b; /* Working buffers/accumulators */
- BNWORD32 *t; /* Pointer into the working buffers */
- BNWORD32 inv; /* mod^-1 modulo 2^32 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(nlen <= mlen);
-
- /* First, a couple of trivial cases. */
- elen = lbnNorm_32(e, elen);
- if (!elen) {
- /* x ^ 0 == 1 */
- lbnZero_32(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- ebits = lbnBits_32(e, elen);
- if (ebits == 1) {
- /* x ^ 1 == x */
- if (n != result)
- lbnCopy_32(result, n, nlen);
- if (mlen > nlen)
- lbnZero_32(BIGLITTLE(result-nlen,result+nlen),
- mlen-nlen);
- return 0;
- }
-
- /* Okay, now move the exponent pointer to the most-significant word */
- e = BIGLITTLE(e-elen, e+elen-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- wbits = 0;
- while (ebits > bnExpModThreshTable[wbits])
- wbits++;
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << wbits;
-
- /* We have the result buffer available, so use it. */
- table[0] = result;
-
- /*
- * Okay, we now have a minimal-sized table - expand it.
- * This is allowed to fail! If so, scale back the table size
- * and proceed.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table[i] = t;
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- wbits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask)
- LBNFREE(table[i], mlen);
-
- /* Okay, fill in the table */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n to Montgomery form */
-
- /* Move n up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_32(t, n, nlen);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+nlen, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_32(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_32(a, t, table[i-1], mod, mlen, inv);
- lbnCopy_32(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* We might use b = n^2 later... */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD32)1 << ((ebits-1) & (32-1)); /* Initialize mask */
-
- /* This should point to the msbit of e */
- assert((*e & bitpos) != 0);
-
- /*
- * Pre-load the window. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e in here.
- *
- * The read-ahead is controlled by elen and the bitpos mask.
- * Note that this is *ahead* of ebits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two wbits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- */
- buf = 0;
- for (i = 0; i <= wbits; i++) {
- buf = (buf << 1) | ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD32)1 << (32-1);
- elen--;
- }
- }
- assert(buf & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- multpos = ebits; /* A NULL value */
- mult = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- ebits--; /* Start processing the first bit... */
- isone = 1;
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf is set, and
- * - We have the extra value n^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf & tblmask);
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (multpos == ebits)
- isone = 0;
-
- /*
- * At this point, the buffer (which is the high half of b) holds
- * either 1 (implicitly, as the "isone" flag is set), or n^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the window
- * - If the most-significant bit of the window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffer
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- ebits--;
-
- /* Advance the window */
- assert(buf < tblmask);
- buf <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by ebits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (elen) {
- buf |= ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD32)1 << (32-1);
- elen--;
- }
- }
-
- /* Examine the window for pending multiplies */
- if (buf & tblmask) {
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
- }
-
- /* If we have a pending multiply, do it */
- if (ebits == multpos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!ebits)
- break;
-
- /* Square the input */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_32(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_32(b, t, mlen);
- lbnZero_32(t, mlen);
- lbnMontReduce_32(b, mod, mlen, inv);
- lbnCopy_32(result, t, mlen);
- /*
- * Clean up - free intermediate storage.
- * Do NOT free table[0], which is the result
- * buffer.
- */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- while (--tblmask)
- LBNFREE(table[tblmask], mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1). When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place. Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future. But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading. The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_32(BNWORD32 *result,
- BNWORD32 const *n1, unsigned n1len,
- BNWORD32 const *e1, unsigned e1len,
- BNWORD32 const *n2, unsigned n2len,
- BNWORD32 const *e2, unsigned e2len,
- BNWORD32 *mod, unsigned mlen)
-{
- BNWORD32 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n1 */
- BNWORD32 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n2 */
- unsigned e1bits, e2bits; /* Exponent bits */
- unsigned w1bits, w2bits; /* Window sizes */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD32 bitpos; /* Mask of current look-ahead bit */
- unsigned buf1, buf2; /* Buffer of exponent bits */
- unsigned mult1pos, mult2pos; /* Where to do pending multiply */
- BNWORD32 const *mult1, *mult2; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD32 *a, *b; /* Working buffers/accumulators */
- BNWORD32 *t; /* Pointer into the working buffers */
- BNWORD32 inv; /* mod^-1 modulo 2^32 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(n1len <= mlen);
- assert(n2len <= mlen);
-
- /* First, a couple of trivial cases. */
- e1len = lbnNorm_32(e1, e1len);
- e2len = lbnNorm_32(e2, e2len);
-
- /* Ensure that the first exponent is the longer */
- e1bits = lbnBits_32(e1, e1len);
- e2bits = lbnBits_32(e2, e2len);
- if (e1bits < e2bits) {
- i = e1len; e1len = e2len; e2len = i;
- i = e1bits; e1bits = e2bits; e2bits = i;
- t = (BNWORD32 *)n1; n1 = n2; n2 = t;
- t = (BNWORD32 *)e1; e1 = e2; e2 = t;
- }
- assert(e1bits >= e2bits);
-
- /* Handle a trivial case */
- if (!e2len)
- return lbnExpMod_32(result, n1, n1len, e1, e1len, mod, mlen);
- assert(e2bits);
-
- /* The code below fucks up if the exponents aren't at least 2 bits */
- if (e1bits == 1) {
- assert(e2bits == 1);
-
- LBNALLOC(a, BNWORD32, n1len+n2len);
- if (!a)
- return -1;
-
- lbnMul_32(a, n1, n1len, n2, n2len);
- /* Do a direct modular reduction */
- if (n1len + n2len >= mlen)
- (void)lbnDiv_32(a+mlen, a, n1len+n2len, mod, mlen);
- lbnCopy_32(result, a, mlen);
- LBNFREE(a, n1len+n2len);
- return 0;
- }
-
- /* Okay, now move the exponent pointers to the most-significant word */
- e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
- e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- w1bits = 0;
- while (e1bits > bnExpModThreshTable[w1bits])
- w1bits++;
- w2bits = 0;
- while (e2bits > bnExpModThreshTable[w2bits])
- w2bits++;
-
- assert(w1bits >= w2bits);
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << w1bits;
- /* Use buf2 for its size, temporarily */
- buf2 = 1u << w2bits;
-
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) {
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return -1;
- }
- table1[0] = t;
- table2[0] = result;
-
- /*
- * Okay, we now have some minimal-sized tables - expand them.
- * This is allowed to fail! If so, scale back the table sizes
- * and proceed. We allocate both tables at the same time
- * so if it fails partway through, they'll both be a reasonable
- * size rather than one huge and one tiny.
- * When i passes buf2 (the number of entries in the e2 window,
- * which may be less than the number of entries in the e1 window),
- * stop allocating e2 space.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table1[i] = t;
- if (i < buf2) {
- LBNALLOC(t, BNWORD32, mlen);
- if (!t) {
- LBNFREE(table1[i], mlen);
- break;
- }
- table2[i] = t;
- }
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- w1bits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask) {
- if (i < buf2)
- LBNFREE(table2[i], mlen);
- LBNFREE(table1[i], mlen);
- }
- /* And shrink the second window too, if needed */
- if (w2bits > w1bits) {
- w2bits = w1bits;
- buf2 = tblmask;
- }
-
- /*
- * From now on, use the w2bits variable for the difference
- * between w1bits and w2bits.
- */
- w2bits = w1bits-w2bits;
-
- /* Okay, fill in the tables */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n1 to Montgomery form */
-
- /* Move n1 up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_32(t, n1, n1len);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+n1len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table1[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_32(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the first table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_32(a, t, table1[i-1], mod, mlen, inv);
- lbnCopy_32(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* Convert n2 to Montgomery form */
-
- t = BIGLITTLE(a-mlen, a+mlen);
- /* Move n2 up "mlen" words into a */
- lbnCopy_32(t, n2, n2len);
- lbnZero_32(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_32(t, a, mlen+n2len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_32(table2[0], a, mlen);
-
- /* Square it into a */
- lbnMontSquare_32(a, table2[0], mod, mlen, inv);
- /* Copy to b, low half */
- lbnCopy_32(b, t, mlen);
-
- /* Use b to initialize the second table */
- for (i = 1; i < buf2; i++) {
- lbnMontMul_32(a, b, table2[i-1], mod, mlen, inv);
- lbnCopy_32(table2[i], t, mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /*
- * Okay, a recap: at this point, the low part of b holds
- * n2^2, the high part holds n1^2, and the tables are
- * initialized with the odd powers of n1 and n2 from 1
- * through 2*tblmask-1 and 2*buf2-1.
- *
- * We might use those squares in b later, or we might not.
- */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD32)1 << ((e1bits-1) & (32-1)); /* Initialize mask */
-
- /* This should point to the msbit of e1 */
- assert((*e1 & bitpos) != 0);
-
- /*
- * Pre-load the windows. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e1 in here.
- *
- * The read-ahead is controlled by e1len and the bitpos mask.
- * Note that this is *ahead* of e1bits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two w1bits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- * e2len is not decremented, it is only ever compared with
- * e1len as *that* is decremented.
- */
- buf1 = buf2 = 0;
- for (i = 0; i <= w1bits; i++) {
- buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD32)1 << (32-1);
- e1len--;
- }
- }
- assert(buf1 & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- mult1pos = mult2pos = e1bits; /* A NULL value */
- mult1 = mult2 = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- isone = 1; /* Buffer is implicitly 1, so replace * by copy */
- e1bits--; /* Start processing the first bit... */
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf1 is set, and
- * - We have the extra value n1^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n1^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n1^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf1 & tblmask);
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (mult1pos == e1bits)
- isone = 0;
-
- /*
- * The first multiply by a power of n2. Similar, but
- * we might not even want to schedule a multiply if e2 is
- * shorter than e1, and the window might be shorter so
- * we have to leave the low w2bits bits alone.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
-
- if (mult2pos == e1bits) {
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- lbnCopy_32(t, b, mlen); /* Copy low to high */
- isone = 0;
- } else {
- lbnMontMul_32(a, t, b, mod, mlen, inv);
- t = a; a = b; b = t;
- }
- }
- }
-
- /*
- * At this point, the buffer (which is the high half of b)
- * holds either 1 (implicitly, as the "isone" flag is set),
- * n1^2, n2^2 or n1^2 * n2^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the windows
- * - If the most-significant bit of a window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffers
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- e1bits--;
-
- /* Advance the windows */
- assert(buf1 < tblmask);
- buf1 <<= 1;
- assert(buf2 < tblmask);
- buf2 <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by e1bits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (e1len) {
- buf1 |= ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 |= ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD32)1 << (32-1);
- e1len--;
- }
- }
-
- /* Examine the first window for pending multiplies */
- if (buf1 & tblmask) {
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
- }
-
- /*
- * Examine the second window for pending multiplies.
- * Window 2 can be smaller than window 1, but we
- * keep the same number of bits in buf2, so we need
- * to ignore any low-order bits in the buffer when
- * computing what to multiply by, and recompute them
- * later.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
- }
-
-
- /* If we have a pending multiply for e1, do it */
- if (e1bits == mult1pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult1, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult1, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* If we have a pending multiply for e2, do it */
- if (e1bits == mult2pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_32(t, mult2, mlen);
- isone = 0;
- } else {
- lbnMontMul_32(a, t, mult2, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!e1bits)
- break;
-
- /* Square the buffer */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_32(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf1);
- assert(!buf2);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_32(b, t, mlen);
- lbnZero_32(t, mlen);
- lbnMontReduce_32(b, mod, mlen, inv);
- lbnCopy_32(result, t, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- buf2 = tblmask >> w2bits;
- while (--tblmask) {
- if (tblmask < buf2)
- LBNFREE(table2[tblmask], mlen);
- LBNFREE(table1[tblmask], mlen);
- }
- t = table1[0];
- LBNFREE(t, mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * 2^exp (mod mod). This is an optimized version for use in Fermat
- * tests. The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_32(BNWORD32 *n, BNWORD32 const *exp, unsigned elen,
- BNWORD32 *mod, unsigned mlen)
-{
- unsigned e; /* Copy of high words of the exponent */
- unsigned bits; /* Assorted counter of bits */
- BNWORD32 const *bitptr;
- BNWORD32 bitword, bitpos;
- BNWORD32 *a, *b, *a1;
- BNWORD32 inv;
- int y; /* Result of bnYield() */
-
- assert(mlen);
-
- bitptr = BIGLITTLE(exp-elen, exp+elen-1);
- bitword = *bitptr;
- assert(bitword);
-
- /* Clear n for future use. */
- lbnZero_32(n, mlen);
-
- bits = lbnBits_32(exp, elen);
-
- /* First, a couple of trivial cases. */
- if (bits <= 1) {
- /* 2 ^ 0 == 1, 2 ^ 1 == 2 */
- BIGLITTLE(n[-1],n[0]) = (BNWORD32)1<<elen;
- return 0;
- }
-
- /* Set bitpos to the most significant bit */
- bitpos = (BNWORD32)1 << ((bits-1) & (32-1));
-
- /* Now, count the bits in the modulus. */
- bits = lbnBits_32(mod, mlen);
- assert(bits > 1); /* a 1-bit modulus is just stupid... */
-
- /*
- * We start with 1<<e, where "e" is as many high bits of the
- * exponent as we can manage without going over the modulus.
- * This first loop finds "e".
- */
- e = 1;
- while (elen) {
- /* Consume the first bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break;
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD32)1<<(32-1);
- }
- e = (e << 1) | ((bitpos & bitword) != 0);
- if (e >= bits) { /* Overflow! Back out. */
- e >>= 1;
- break;
- }
- }
- /*
- * The bit in "bitpos" being examined by the bit buffer has NOT
- * been consumed yet. This may be past the end of the exponent,
- * in which case elen == 1.
- */
-
- /* Okay, now, set bit "e" in n. n is already zero. */
- inv = (BNWORD32)1 << (e & (32-1));
- e /= 32;
- BIGLITTLE(n[-e-1],n[e]) = inv;
- /*
- * The effective length of n in words is now "e+1".
- * This is used a little bit later.
- */
-
- if (!elen)
- return 0; /* That was easy! */
-
- /*
- * We have now processed the first few bits. The next step
- * is to convert this to Montgomery form for further squaring.
- */
-
- /* Allocate working storage: two product buffers */
- LBNALLOC(a, BNWORD32, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_32(inv);
- /* Move n (length e+1, remember?) up "mlen" words into b */
- /* Note that we lie about a1 for a bit - it's pointing to b */
- a1 = BIGLITTLE(b-mlen,b+mlen);
- lbnCopy_32(a1, n, e+1);
- lbnZero_32(b, mlen);
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_32(a1, b, mlen+e+1, mod, mlen);
- /*
- * Now do the first squaring and modular reduction to put
- * the number up in a1 where it belongs.
- */
- lbnMontSquare_32(a, b, mod, mlen, inv);
- /* Fix up a1 to point to where it should go. */
- a1 = BIGLITTLE(a-mlen,a+mlen);
-
- /*
- * Okay, now, a1 holds the number being accumulated, and
- * b is a scratch register. Start working:
- */
- for (;;) {
- /*
- * Is the bit set? If so, double a1 as well.
- * A modular doubling like this is very cheap.
- */
- if (bitpos & bitword) {
- /*
- * Double the number. If there was a carry out OR
- * the result is greater than the modulus, subract
- * the modulus.
- */
- if (lbnDouble_32(a1, mlen) ||
- lbnCmp_32(a1, mod, mlen) > 0)
- (void)lbnSubN_32(a1, mod, mlen);
- }
-
- /* Advance to the next exponent bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break; /* Done! */
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD32)1<<(32-1);
- }
-
- /*
- * The elen/bitword/bitpos bit buffer is known to be
- * non-empty, i.e. there is at least one more unconsumed bit.
- * Thus, it's safe to square the number.
- */
- lbnMontSquare_32(b, a1, mod, mlen, inv);
- /* Rename result (in b) back to a (a1, really). */
- a1 = b; b = a; a = a1;
- a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* DONE! Just a little bit of cleanup... */
-
- /*
- * Convert result out of Montgomery form... this is
- * just a Montgomery reduction.
- */
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(n, a1, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_32(BNWORD32 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD32 t = 0; /* Needed to shut up uninitialized var warnings */
- unsigned shift;
-
- lsbyte += buflen;
-
- shift = (8 * lsbyte) % 32;
- lsbyte /= (32/8); /* Convert to word offset */
- BIGLITTLE(n -= lsbyte, n += lsbyte);
-
- if (shift)
- t = BIGLITTLE(n[-1],n[0]);
-
- while (buflen--) {
- if (!shift) {
- t = BIGLITTLE(*n++,*--n);
- shift = 32;
- }
- shift -= 8;
- *buf++ = (unsigned char)(t>>shift);
- }
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD32 t = 0; /* Shut up uninitialized varibale warnings */
-
- lsbyte += buflen;
-
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 32;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *buf++;
- if ((--lsbyte % (32/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 32;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_32(BNWORD32 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD32 t = 0; /* Needed to shut up uninitialized var warnings */
-
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte % (32/8)) * 8 ;
- }
-
- while (buflen--) {
- if ((lsbyte++ % (32/8)) == 0)
- t = BIGLITTLE(*--n,*n++);
- *buf++ = (unsigned char)t;
- t >>= 8;
- }
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD32 t = 0; /* Shut up uninitialized varibale warnings */
-
- /* Move to most-significant end */
- lsbyte += buflen;
- buf += buflen;
-
- BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (32/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 32;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *--buf;
- if ((--lsbyte % (32/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 32;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-#ifdef DEADCODE /* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "32/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_32(BNWORD32 *a, unsigned char const *b, unsigned blen)
-{
- BNWORD32 t;
- unsigned alen = (blen + (32/8-1))/(32/8);
- BIGLITTLE(a -= alen, a += alen);
-
- while (blen) {
- t = 0;
- do {
- t = t << 8 | *b++;
- } while (--blen & (32/8-1));
- BIGLITTLE(*a++,*--a) = t;
- }
- return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b. Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash. The return value
- * indicates which: 0 for a, and 1 for b. The length of the retult is
- * returned in rlen. Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_32(BNWORD32 *a, unsigned alen, BNWORD32 *b, unsigned blen,
- unsigned *rlen)
-{
-#if BNYIELD
- int y;
-#endif
- assert(alen >= blen);
-
- while (blen != 0) {
- (void)lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- alen = lbnNorm_32(a, blen);
- if (alen == 0) {
- *rlen = blen;
- return 1;
- }
- (void)lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- blen = lbnNorm_32(b, alen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- return y;
-#endif
- }
- *rlen = alen;
- return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1. Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod". It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_32(BNWORD32 *a, unsigned alen, BNWORD32 const *mod, unsigned mlen)
-{
- BNWORD32 *b; /* Hold a copy of mod during GCD reduction */
- BNWORD32 *p; /* Temporary for products added to t0 and t1 */
- BNWORD32 *t0, *t1; /* Inverse accumulators */
- BNWORD32 cy;
- unsigned blen, t0len, t1len, plen;
- int y;
-
- alen = lbnNorm_32(a, alen);
- if (!alen)
- return 1; /* No inverse */
-
- mlen = lbnNorm_32(mod, mlen);
-
- assert (alen <= mlen);
-
- /* Inverse of 1 is 1 */
- if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
- lbnZero_32(BIGLITTLE(a-alen,a+alen), mlen-alen);
- return 0;
- }
-
- /* Allocate a pile of space */
- LBNALLOC(b, BNWORD32, mlen+1);
- if (b) {
- /*
- * Although products are guaranteed to always be less than the
- * modulus, it can involve multiplying two 3-word numbers to
- * get a 5-word result, requiring a 6th word to store a 0
- * temporarily. Thus, mlen + 1.
- */
- LBNALLOC(p, BNWORD32, mlen+1);
- if (p) {
- LBNALLOC(t0, BNWORD32, mlen);
- if (t0) {
- LBNALLOC(t1, BNWORD32, mlen);
- if (t1)
- goto allocated;
- LBNFREE(t0, mlen);
- }
- LBNFREE(p, mlen+1);
- }
- LBNFREE(b, mlen+1);
- }
- return -1;
-
-allocated:
-
- /* Set t0 to 1 */
- t0len = 1;
- BIGLITTLE(t0[-1],t0[0]) = 1;
-
- /* b = mod */
- lbnCopy_32(b, mod, mlen);
- /* blen = mlen (implicitly) */
-
- /* t1 = b / a; b = b % a */
- cy = lbnDiv_32(t1, b, mlen, a, alen);
- *(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
- t1len = lbnNorm_32(t1, mlen-alen+1);
- blen = lbnNorm_32(b, alen);
-
- /* while (b > 1) */
- while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD32)1) {
- /* q = a / b; a = a % b; */
- if (alen < blen || (alen == blen && lbnCmp_32(a, a, alen) < 0))
- assert(0);
- cy = lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- *(BIGLITTLE(a-alen-1,a+alen)) = cy;
- plen = lbnNorm_32(BIGLITTLE(a-blen,a+blen), alen-blen+1);
- assert(plen);
- alen = lbnNorm_32(a, blen);
- if (!alen)
- goto failure; /* GCD not 1 */
-
- /* t0 += q * t1; */
- assert(plen+t1len <= mlen+1);
- lbnMul_32(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
- plen = lbnNorm_32(p, plen + t1len);
- assert(plen <= mlen);
- if (plen > t0len) {
- lbnZero_32(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
- t0len = plen;
- }
- cy = lbnAddN_32(t0, p, plen);
- if (cy) {
- if (t0len > plen) {
- cy = lbnAdd1_32(BIGLITTLE(t0-plen,t0+plen),
- t0len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
- t0len++;
- }
- }
-
- /* if (a <= 1) return a ? t0 : FAIL; */
- if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD32)1) {
- if (alen == 0)
- goto failure; /* FAIL */
- assert(t0len <= mlen);
- lbnCopy_32(a, t0, t0len);
- lbnZero_32(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
- goto success;
- }
-
- /* q = b / a; b = b % a; */
- if (blen < alen || (blen == alen && lbnCmp_32(b, a, alen) < 0))
- assert(0);
- cy = lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- *(BIGLITTLE(b-blen-1,b+blen)) = cy;
- plen = lbnNorm_32(BIGLITTLE(b-alen,b+alen), blen-alen+1);
- assert(plen);
- blen = lbnNorm_32(b, alen);
- if (!blen)
- goto failure; /* GCD not 1 */
-
- /* t1 += q * t0; */
- assert(plen+t0len <= mlen+1);
- lbnMul_32(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
- plen = lbnNorm_32(p, plen + t0len);
- assert(plen <= mlen);
- if (plen > t1len) {
- lbnZero_32(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
- t1len = plen;
- }
- cy = lbnAddN_32(t1, p, plen);
- if (cy) {
- if (t1len > plen) {
- cy = lbnAdd1_32(BIGLITTLE(t1-plen,t0+plen),
- t1len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
- t1len++;
- }
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
-
- if (!blen)
- goto failure; /* gcd(a, mod) != 1 -- FAIL */
-
- /* return mod-t1 */
- lbnCopy_32(a, mod, mlen);
- assert(t1len <= mlen);
- cy = lbnSubN_32(a, t1, t1len);
- if (cy) {
- assert(mlen > t1len);
- cy = lbnSub1_32(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
- assert(!cy);
- }
-
-success:
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return 0;
-
-failure: /* GCD is not 1 - no inverse exists! */
- y = 1;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod". Compute them every "bits"
- * for "n" steps. This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- *
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_32(BNWORD32 **array, unsigned n, unsigned bits,
- BNWORD32 const *g, unsigned glen, BNWORD32 *mod, unsigned mlen)
-{
- BNWORD32 *a, *b; /* Temporary double-width accumulators */
- BNWORD32 *a1; /* Pointer to high half of a*/
- BNWORD32 inv; /* Montgomery inverse of LSW of mod */
- BNWORD32 *t;
- unsigned i;
-
- glen = lbnNorm_32(g, glen);
- assert(glen);
-
- assert (mlen == lbnNorm_32(mod, mlen));
- assert (glen <= mlen);
-
- /* Allocate two temporary buffers, and the array slots */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD32, mlen*2);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Okay, all ready */
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_32(inv);
- /* Move g up "mlen" words into a (clearing the low mlen words) */
- a1 = BIGLITTLE(a-mlen,a+mlen);
- lbnCopy_32(a1, g, glen);
- lbnZero_32(a, mlen);
-
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_32(a1, a, mlen+glen, mod, mlen);
-
- /* Copy the first value into the array */
- t = *array;
- lbnCopy_32(t, a, mlen);
- a1 = a; /* This first value is *not* shifted up */
-
- /* Now compute the remaining n-1 array entries */
- assert(bits);
- assert(n);
- while (--n) {
- i = bits;
- do {
- /* Square a1 into b1 */
- lbnMontSquare_32(b, a1, mod, mlen, inv);
- t = b; b = a; a = t;
- a1 = BIGLITTLE(a-mlen, a+mlen);
- } while (--i);
- t = *++array;
- lbnCopy_32(t, a1, mlen);
- }
-
- /* Hooray, we're done. */
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return 0;
-}
-
-/*
- * result = base^exp (mod mod). "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart. (I.e. array[i]
- * is base^(2^(i*bits))).
- *
- * The algorithm consists of:
- * a = b = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_32(BNWORD32 *result, BNWORD32 const * const *array,
- unsigned bits, BNWORD32 const *exp, unsigned elen,
- BNWORD32 const *mod, unsigned mlen)
-{
- BNWORD32 *a, *b, *c, *t;
- BNWORD32 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD32 const *eptr; /* Pointer into exp */
- BNWORD32 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD32 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
-
- mlen = lbnNorm_32(mod, mlen);
- assert (mlen);
-
- elen = lbnNorm_32(exp, elen);
- if (!elen) {
- lbnZero_32(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD32, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD32, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Set up bit buffer for walking the exponent */
- eptr = exp;
- buf = BIGLITTLE(*--eptr, *eptr++);
- ewords = elen-1;
- bufbits = 32;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 32;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD32 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_32(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_32(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_32(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_32(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod). "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart. (I.e. array1[i] is base1^(2^(i*bits))).
- *
- * Bits must be the same in both. (It could be made adjustable, but it's
- * a bit of a pain. Just make them both equal to the larger one.)
- *
- * The algorithm consists of:
- * a = b = (powers of base1 and base2 to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_32(BNWORD32 *result, unsigned bits,
- BNWORD32 const * const *array1, BNWORD32 const *exp1, unsigned elen1,
- BNWORD32 const * const *array2, BNWORD32 const *exp2,
- unsigned elen2, BNWORD32 const *mod, unsigned mlen)
-{
- BNWORD32 *a, *b, *c, *t;
- BNWORD32 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j, k; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD32 const *eptr; /* Pointer into exp */
- BNWORD32 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD32 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
- BNWORD32 const * const *array;
-
- mlen = lbnNorm_32(mod, mlen);
- assert (mlen);
-
- elen1 = lbnNorm_32(exp1, elen1);
- if (!elen1) {
- return lbnBasePrecompExp_32(result, array2, bits, exp2, elen2,
- mod, mlen);
- }
- elen2 = lbnNorm_32(exp2, elen2);
- if (!elen2) {
- return lbnBasePrecompExp_32(result, array1, bits, exp1, elen1,
- mod, mlen);
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen1);
- assert(elen2);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD32, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD32, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD32, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Walk each exponent in turn */
- for (k = 0; k < 2; k++) {
- /* Set up the exponent for walking */
- array = k ? array2 : array1;
- eptr = k ? exp2 : exp1;
- ewords = (k ? elen2 : elen1) - 1;
- /* Set up bit buffer for walking the exponent */
- buf = BIGLITTLE(*--eptr, *eptr++);
- bufbits = 32;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 32;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD32 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_32(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_32(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_32(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_32(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_32(a, a1, mlen);
- lbnZero_32(a1, mlen);
- lbnMontReduce_32(a, mod, mlen, inv);
- lbnCopy_32(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn32.h b/jni/libzrtp/sources/bnlib/lbn32.h
deleted file mode 100644
index e975550..0000000
--- a/jni/libzrtp/sources/bnlib/lbn32.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN32_H
-#define LBN32_H
-
-#include "lbn.h"
-
-#ifndef BNWORD32
-#error 32-bit bignum library requires a 32-bit data type
-#endif
-
-#ifndef lbnCopy_32
-void lbnCopy_32(BNWORD32 *dest, BNWORD32 const *src, unsigned len);
-#endif
-#ifndef lbnZero_32
-void lbnZero_32(BNWORD32 *num, unsigned len);
-#endif
-#ifndef lbnNeg_32
-void lbnNeg_32(BNWORD32 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_32
-BNWORD32 lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry);
-#endif
-#ifndef lbnSub1_32
-BNWORD32 lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow);
-#endif
-
-#ifndef lbnAddN_32
-BNWORD32 lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_32
-BNWORD32 lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_32
-int lbnCmp_32(BNWORD32 const *num1, BNWORD32 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_32
-void lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-#ifndef lbnMulAdd1_32
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-#ifndef lbnMulSub1_32
-BNWORD32 lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-
-#ifndef lbnLshift_32
-BNWORD32 lbnLshift_32(BNWORD32 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_32
-BNWORD32 lbnDouble_32(BNWORD32 *num, unsigned len);
-#endif
-#ifndef lbnRshift_32
-BNWORD32 lbnRshift_32(BNWORD32 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_32
-void lbnMul_32(BNWORD32 *prod, BNWORD32 const *num1, unsigned len1,
- BNWORD32 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_32
-void lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_32
-unsigned lbnNorm_32(BNWORD32 const *num, unsigned len);
-#endif
-#ifndef lbnBits_32
-unsigned lbnBits_32(BNWORD32 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_32
-void lbnExtractBigBytes_32(BNWORD32 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_32
-void lbnInsertBigBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_32
-void lbnExtractLittleBytes_32(BNWORD32 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_32
-void lbnInsertLittleBytes_32(BNWORD32 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_32
-BNWORD32 lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d);
-#endif
-#ifndef lbnDiv1_32
-BNWORD32 lbnDiv1_32(BNWORD32 *q, BNWORD32 *rem,
- BNWORD32 const *n, unsigned len, BNWORD32 d);
-#endif
-#ifndef lbnModQ_32
-unsigned lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_32
-BNWORD32
-lbnDiv_32(BNWORD32 *q, BNWORD32 *n, unsigned nlen, BNWORD32 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_32
-BNWORD32 lbnMontInv1_32(BNWORD32 const x);
-#endif
-#ifndef lbnMontReduce_32
-void lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned const mlen,
- BNWORD32 inv);
-#endif
-#ifndef lbnToMont_32
-void lbnToMont_32(BNWORD32 *n, unsigned nlen, BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_32
-void lbnFromMont_32(BNWORD32 *n, BNWORD32 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_32
-int lbnExpMod_32(BNWORD32 *result, BNWORD32 const *n, unsigned nlen,
- BNWORD32 const *exp, unsigned elen, BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_32
-int lbnDoubleExpMod_32(BNWORD32 *result,
- BNWORD32 const *n1, unsigned n1len, BNWORD32 const *e1, unsigned e1len,
- BNWORD32 const *n2, unsigned n2len, BNWORD32 const *e2, unsigned e2len,
- BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_32
-int lbnTwoExpMod_32(BNWORD32 *n, BNWORD32 const *exp, unsigned elen,
- BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_32
-int lbnGcd_32(BNWORD32 *a, unsigned alen, BNWORD32 *b, unsigned blen,
- unsigned *rlen);
-#endif
-#ifndef lbnInv_32
-int lbnInv_32(BNWORD32 *a, unsigned alen, BNWORD32 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_32(BNWORD32 **array, unsigned n, unsigned bits,
- BNWORD32 const *g, unsigned glen, BNWORD32 *mod, unsigned mlen);
-int lbnBasePrecompExp_32(BNWORD32 *result, BNWORD32 const * const *array,
- unsigned bits, BNWORD32 const *exp, unsigned elen,
- BNWORD32 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_32(BNWORD32 *result, unsigned bits,
- BNWORD32 const * const *array1, BNWORD32 const *exp1, unsigned elen1,
- BNWORD32 const * const *array2, BNWORD32 const *exp2,
- unsigned elen2, BNWORD32 const *mod, unsigned mlen);
-
-#endif /* LBN32_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn64.c b/jni/libzrtp/sources/bnlib/lbn64.c
deleted file mode 100644
index e930652..0000000
--- a/jni/libzrtp/sources/bnlib/lbn64.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn64.c - Low-level bignum routines, 64-bit version.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "64" and "128" appear in many places in this
- * file, including inside identifiers. Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly. Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions. Any reference to the number of bits
- * in a word must be the string "64", and that string must not appear
- * otherwise. Any reference to twice this number must appear as "128",
- * which likewise must not appear otherwise. Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (128)
- * first, then the smaller (64). When halving the bit size, do the
- * opposite. Otherwise, things will get wierd. Also, be sure to replace
- * every instance that appears. (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD64s. The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way. If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END. The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1]. This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative. The expression used in this
- * code, *(ptr-i) will, however, work. (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this. An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names. If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made. Use the BNINCLUDE file to do that. Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_64 lbnMulAdd1_64
- *
- * If you want to write asm routines, start with lbnMulAdd1_64().
- * This is the workhorse of modular exponentiation. lbnMulN1_64() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_64 if that has a custom version. lbnMulSub1_64 and
- * lbnDiv21_64 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_64 defined, writing the other two should
- * be pretty easy. (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_64 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD128)
- * type are lbnMulAdd1_64 and lbnMulSub1_64; if those are provided,
- * the rest follows. lbnDiv21_64, however, is a lot slower unless you
- * have them, and lbnModQ_64 takes after it. That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn64.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD64
-#error 64-bit bignum library requires a 64-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void); /* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach. One big advantage of this is that the assembly
- * support routines are simpler. The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach. This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster. Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default. Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries. I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words. <Marvin mode on> Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD64)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_64
-void
-lbnCopy_64(BNWORD64 *dest, BNWORD64 const *src, unsigned len)
-{
- memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
- len * sizeof(*src));
-}
-#endif /* !lbnCopy_64 */
-
-/*
- * Fill n words with zero. This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't. Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_64
-void
-lbnZero_64(BNWORD64 *num, unsigned len)
-{
- while (len--)
- BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_64 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero. Negating low-order words
- * entails doing nothing until a non-zero word is hit. Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit. Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_64
-void
-lbnNeg_64(BNWORD64 *num, unsigned len)
-{
- assert(len);
-
- /* Skip low-order zero words */
- while (BIGLITTLE(*--num,*num) == 0) {
- if (!--len)
- return;
- LITTLE(num++;)
- }
- /* Negate the lowest-order non-zero word */
- *num = -*num;
- /* Complement all the higher-order words */
- while (--len) {
- BIGLITTLE(--num,++num);
- *num = ~*num;
- }
-}
-#endif /* !lbnNeg_64 */
-
-
-/*
- * lbnAdd1_64: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex. After adding the first carry, which may
- * be > 1, compare the sum and the carry. If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^64) which is larger than
- * the other input can possibly be. If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap. Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_64 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD128
-BNWORD64
-lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry)
-{
- BNWORD128 t;
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- t = (BNWORD128)BIGLITTLE(*--num,*num) + carry;
- BIGLITTLE(*num,*num++) = (BNWORD64)t;
- if ((t >> 64) == 0)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry)
-{
- assert(len > 0); /* Alternative: if (!len) return carry */
-
- if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
- return 0;
- while (--len) {
- if (++BIGLITTLE(*--num,*num++) != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif/* !lbnAdd1_64 */
-
-/*
- * lbnSub1_64: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above. If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry. If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow. If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0. To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD64). If the size of an int is larger
- * than BNWORD64, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_64 /* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD128
-BNWORD64
-lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow)
-{
- BNWORD128 t;
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- t = (BNWORD128)BIGLITTLE(*--num,*num) - borrow;
- BIGLITTLE(*num,*num++) = (BNWORD64)t;
- if ((t >> 64) == 0)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow)
-{
- assert(len > 0); /* Alternative: if (!len) return borrow */
-
- if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD64)~borrow)
- return 0;
- while (--len) {
- if ((BIGLITTLE(*--num,*num++))-- != 0)
- return 0;
- }
- return 1;
-}
-#endif
-#endif /* !lbnSub1_64 */
-
-/*
- * lbnAddN_64: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry. If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs. Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true. The first can
- * only be true if carry == 1 and x, the result, is 0. In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_64
-#ifdef BNWORD128
-BNWORD64
-lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
- BNWORD128 t;
-
- assert(len > 0);
-
- t = (BNWORD128)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
- while (--len) {
- t = (BNWORD128)BIGLITTLE(*--num1,*num1) +
- (BNWORD128)BIGLITTLE(*--num2,*num2++) + (t >> 64);
- BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
- }
-
- return (BNWORD64)(t>>64);
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
- BNWORD64 x, carry = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- carry = (x += carry) < carry;
- carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
- } while (--len);
-
- return carry;
-}
-#endif
-#endif /* !lbnAddN_64 */
-
-/*
- * lbnSubN_64: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again. Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true. The first can only be true if
- * borrow == 1 and x, the result, is 0. In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD64)-(t>>64) is subtracted, rather than
- * adding t>>64, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_64
-#ifdef BNWORD128
-BNWORD64
-lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
- BNWORD128 t;
-
- assert(len > 0);
-
- t = (BNWORD128)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
- BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
-
- while (--len) {
- t = (BNWORD128)BIGLITTLE(*--num1,*num1) -
- (BNWORD128)BIGLITTLE(*--num2,*num2++) - (BNWORD64)-(t >> 64);
- BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
- }
-
- return -(BNWORD64)(t>>64);
-}
-#else
-BNWORD64
-lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
- BNWORD64 x, borrow = 0;
-
- assert(len > 0); /* Alternative: change loop to test at start */
-
- do {
- x = BIGLITTLE(*--num2,*num2++);
- borrow = (x += borrow) < borrow;
- borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD64)~x;
- } while (--len);
-
- return borrow;
-}
-#endif
-#endif /* !lbnSubN_64 */
-
-#ifndef lbnCmp_64
-/*
- * lbnCmp_64: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- *
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_64(BNWORD64 const *num1, BNWORD64 const *num2, unsigned len)
-{
- BIGLITTLE(num1 -= len, num1 += len);
- BIGLITTLE(num2 -= len, num2 += len);
-
- while (len--) {
- if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
- if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
- return -1;
- else
- return 1;
- }
- }
- return 0;
-}
-#endif /* !lbnCmp_64 */
-
-/*
- * mul64_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b. mul64_ppmma and mul64_ppmm
- * are simpler versions. If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul64_ppmma) && defined(mul64_ppmmaa)
-#define mul64_ppmma(ph,pl,x,y,a) mul64_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul64_ppmm) && defined(mul64_ppmma)
-#define mul64_ppmm(ph,pl,x,y) mul64_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul64_ppmm-based operations on machines
- * that do not provide mul64_ppmm. Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul64_ppmm) && defined(BNWORD128) && 0 /* Debugging */
-#define mul64_ppmm(ph,pl,x,y) \
- ({BNWORD128 _ = (BNWORD128)(x)*(y); (pl) = _; (ph) = _>>64;})
-#endif
-
-#if defined(mul64_ppmm) && !defined(mul64_ppmma)
-#define mul64_ppmma(ph,pl,x,y,a) \
- (mul64_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul64_ppmma) && !defined(mul64_ppmmaa)
-#define mul64_ppmmaa(ph,pl,x,y,a,b) \
- (mul64_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_64: Multiply an n-word input by a 1-word input and store the
- * n+1-word product. This uses either the mul64_ppmm and mul64_ppmma
- * macros, or C multiplication with the BNWORD128 type. This uses mul64_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_64
-#ifdef lbnMulAdd1_64 /* If we have this asm primitive, use it. */
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- lbnZero_64(out, len);
- BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_64(out, in, len, k);
-}
-#elif defined(mul64_ppmm)
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD64 carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- mul64_ppmm(carry, *out, *in, k);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;)
- carryin = carry;
- mul64_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
- }
- BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD128)
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD128 p;
-
- assert(len > 0);
-
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k;
- BIGLITTLE(*--out,*out++) = (BNWORD64)p;
-
- while (--len) {
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + (BNWORD64)(p >> 64);
- BIGLITTLE(*--out,*out++) = (BNWORD64)p;
- }
- BIGLITTLE(*--out,*out) = (BNWORD64)(p >> 64);
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* lbnMulN1_64 */
-
-/*
- * lbnMulAdd1_64: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination. *Returns the n+1st word
- * of the product.* (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.) This uses either the mul64_ppmma and mul64_ppmmaa macros,
- * or C multiplication with the BNWORD128 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with. It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_64
-#if defined(mul64_ppmm)
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD64 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--out;--in;);
- carryin = *out;
- mul64_ppmma(carry, *out, *in, k, carryin);
- LITTLE(out++;in++;)
-
- while (--len) {
- BIG(--out;--in;);
- carryin = carry;
- mul64_ppmmaa(carry, prod, *in, k, carryin, *out);
- *out = prod;
- LITTLE(out++;in++;)
- }
-
- return carry;
-}
-#elif defined(BNWORD128)
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD128 p;
-
- assert(len > 0);
-
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD64)p;
-
- while (--len) {
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k +
- (BNWORD64)(p >> 64) + BIGLITTLE(*--out,*out);
- BIGLITTLE(*out,*out++) = (BNWORD64)p;
- }
-
- return (BNWORD64)(p >> 64);
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* lbnMulAdd1_64 */
-
-/*
- * lbnMulSub1_64: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination. Returns the n+1st word of the product.
- * This uses either the mul64_ppmm and mul64_ppmma macros, or
- * C multiplication with the BNWORD128 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_64
-#if defined(mul64_ppmm)
-BNWORD64
-lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD64 prod, carry, carryin;
-
- assert(len > 0);
-
- BIG(--in;)
- mul64_ppmm(carry, prod, *in, k);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD64)~prod;
-
- while (--len) {
- BIG(--in;);
- carryin = carry;
- mul64_ppmma(carry, prod, *in, k, carryin);
- LITTLE(in++;)
- carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD64)~prod;
- }
-
- return carry;
-}
-#elif defined(BNWORD128)
-BNWORD64
-lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
- BNWORD128 p;
- BNWORD64 carry, t;
-
- assert(len > 0);
-
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD64)(p>>64) + ((BIGLITTLE(*out,*out++)=t-(BNWORD64)p) > t);
-
- while (--len) {
- p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + carry;
- t = BIGLITTLE(*--out,*out);
- carry = (BNWORD64)(p>>64) +
- ( (BIGLITTLE(*out,*out++)=t-(BNWORD64)p) > t );
- }
-
- return carry;
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* !lbnMulSub1_64 */
-
-/*
- * Shift n words left "shift" bits. 0 < shift < 64. Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_64
-BNWORD64
-lbnLshift_64(BNWORD64 *num, unsigned len, unsigned shift)
-{
- BNWORD64 x, carry;
-
- assert(shift > 0);
- assert(shift < 64);
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<shift) | carry;
- LITTLE(num++;)
- carry = x >> (64-shift);
- }
- return carry;
-}
-#endif /* !lbnLshift_64 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_64
-BNWORD64
-lbnDouble_64(BNWORD64 *num, unsigned len)
-{
- BNWORD64 x, carry;
-
- carry = 0;
- while (len--) {
- BIG(--num;)
- x = *num;
- *num = (x<<1) | carry;
- LITTLE(num++;)
- carry = x >> (64-1);
- }
- return carry;
-}
-#endif /* !lbnDouble_64 */
-
-/*
- * Shift n words right "shift" bits. 0 < shift < 64. Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_64
-BNWORD64
-lbnRshift_64(BNWORD64 *num, unsigned len, unsigned shift)
-{
- BNWORD64 x, carry = 0;
-
- assert(shift > 0);
- assert(shift < 64);
-
- BIGLITTLE(num -= len, num += len);
-
- while (len--) {
- LITTLE(--num;)
- x = *num;
- *num = (x>>shift) | carry;
- BIG(num++;)
- carry = x << (64-shift);
- }
- return carry >> (64-shift);
-}
-#endif /* !lbnRshift_64 */
-
-/*
- * Multiply two numbers of the given lengths. prod and num2 may overlap,
- * provided that the low len1 bits of prod are free. (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_64.)
- *
- * TODO: Use Karatsuba multiply. The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_64
-void
-lbnMul_64(BNWORD64 *prod, BNWORD64 const *num1, unsigned len1,
- BNWORD64 const *num2, unsigned len2)
-{
- /* Special case of zero */
- if (!len1 || !len2) {
- lbnZero_64(prod, len1+len2);
- return;
- }
-
- /* Multiply first word */
- lbnMulN1_64(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
- /*
- * Add in subsequent words, storing the most significant word,
- * which is new each time.
- */
- while (--len2) {
- BIGLITTLE(--prod,prod++);
- BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
- lbnMulAdd1_64(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
- }
-}
-#endif /* !lbnMul_64 */
-
-/*
- * lbnMulX_64 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_64
-#if defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster. It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_64(BNWORD64 *prod, BNWORD64 const *num1, BNWORD64 const *num2,
- unsigned len)
-{
- BNWORD128 x, y;
- BNWORD64 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- x = (BNWORD128)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD64)x;
- x >>= 64;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- for (j = 0; j <= i; j++) {
- BIG(y = (BNWORD128)*--p1 * *p2++;)
- LITTLE(y = (BNWORD128)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- for (j = i; j < len; j++) {
- BIG(y = (BNWORD128)*--p1 * *p2++;)
- LITTLE(y = (BNWORD128)*p1++ * *--p2;)
- x += y;
- carry += (x < y);
- }
- BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
-
- BIGLITTLE(*--prod,*prod) = (BNWORD64)x;
-}
-#else /* !defined(BNWORD128) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_64(prod, num1, num2, len) lbnMul_64(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD128) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_64 */
-
-#if !defined(lbnMontMul_64) && defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply. This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops. The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers. These are stored in the product array,
- * which contains no data as of yet. x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_64(BNWORD64 *prod, BNWORD64 const *num1, BNWORD64 const *num2,
- BNWORD64 const *mod, unsigned len, BNWORD64 inv)
-{
- BNWORD128 x, y;
- BNWORD64 const *p1, *p2, *pm;
- BNWORD64 *pp;
- BNWORD64 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /*
- * This computes directly into the high half of prod, so just
- * shift the pointer and consider prod only "len" elements long
- * for the rest of the code.
- */
- BIGLITTLE(prod -= len, prod += len);
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- x = (BNWORD128)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
- BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD64)x;
- y = (BNWORD128)t * BIGLITTLE(mod[-1],mod[0]);
- x += y;
- /* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
- carry = (x < y);
- assert((BNWORD64)x == 0);
- x = x >> 64 | (BNWORD128)carry << 64;
-
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = num1;
- p2 = BIGLITTLE(num2-i-1,num2+i+1);
- pp = prod;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD128)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD128)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
- x += y;
- carry += (x < y);
- }
- y = (BNWORD128)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
- x += y;
- carry += (x < y);
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD64)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD128)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD64)x == 0);
- x = x >> 64 | (BNWORD128)carry << 64;
- }
-
- /* Pass 2 - compute reduced product and store */
- for (i = 1; i < len; i++) {
- carry = 0;
- p1 = BIGLITTLE(num1-i,num1+i);
- p2 = BIGLITTLE(num2-len,num2+len);
- pm = BIGLITTLE(mod-i,mod+i);
- pp = BIGLITTLE(prod-len,prod+len);
- for (j = i; j < len; j++) {
- y = (BNWORD128)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
- x += y;
- carry += (x < y);
- y = (BNWORD128)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-len, pm == mod+len));
- assert(BIGLITTLE(pp == prod-i, pp == prod+i));
- BIGLITTLE(pp[0],pp[-1]) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
-
- /* Last round of second half, simplified. */
- BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD64)x;
- carry = (x >> 64);
-
- while (carry)
- carry -= lbnSubN_64(prod, mod, len);
- while (lbnCmp_64(prod, mod, len) >= 0)
- (void)lbnSubN_64(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_64 lbnMontMul_64
-#endif
-
-#if !defined(lbnSquare_64) && defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring. This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len)
-{
- BNWORD128 x, y, z;
- BNWORD64 const *p1, *p2;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!len)
- return;
-
- /* Word 0 of product */
- x = (BNWORD128)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
- BIGLITTLE(*--prod, *prod++) = (BNWORD64)x;
- x >>= 64;
-
- /* Words 1 through len-1 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = num;
- p2 = BIGLITTLE(num-i-1,num+i+1);
- for (j = 0; j < (i+1)/2; j++) {
- BIG(z = (BNWORD128)*--p1 * *p2++;)
- LITTLE(z = (BNWORD128)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((i & 1) == 0) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD128)*p2 * *p2;)
- LITTLE(z = (BNWORD128)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
- /* Words len through 2*len-2 */
- for (i = 1; i < len; i++) {
- carry = 0;
- y = 0;
- p1 = BIGLITTLE(num-i,num+i);
- p2 = BIGLITTLE(num-len,num+len);
- for (j = 0; j < (len-i)/2; j++) {
- BIG(z = (BNWORD128)*--p1 * *p2++;)
- LITTLE(z = (BNWORD128)*p1++ * *--p2;)
- y += z;
- carry += (y < z);
- }
- y += z = y;
- carry += carry + (y < z);
- if ((len-i) & 1) {
- assert(BIGLITTLE(--p1 == p2, p1 == --p2));
- BIG(z = (BNWORD128)*p2 * *p2;)
- LITTLE(z = (BNWORD128)*p1 * *p1;)
- y += z;
- carry += (y < z);
- }
- x += y;
- carry += (x < y);
- BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
-
- /* Word 2*len-1 */
- BIGLITTLE(*--prod,*prod) = (BNWORD64)x;
-}
-/* Suppress later definition */
-#define lbnSquare_64 lbnSquare_64
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed. There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- * a b c d e
- * * a b c d e
- * ==================
- * ae be ce de ee
- * ad bd cd dd de
- * ac bc cc cd ce
- * ab bb bc bd be
- * aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- * ae be ce de = (abcd) * e
- * ad bd cd = (abc) * d
- * ac bc = (ab) * c
- * ab = (a) * b
- *
- * is a copy of everything below the main diagonal:
- * de
- * cd ce
- * bc bd be
- * ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again. The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba. (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_64
-void
-lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len)
-{
- BNWORD64 t;
- BNWORD64 *prodx = prod; /* Working copy of the argument */
- BNWORD64 const *numx = num; /* Working copy of the argument */
- unsigned lenx = len; /* Working copy of the argument */
-
- if (!len)
- return;
-
- /* First, store all the squares */
- while (lenx--) {
-#ifdef mul64_ppmm
- BNWORD64 ph, pl;
- t = BIGLITTLE(*--numx,*numx++);
- mul64_ppmm(ph,pl,t,t);
- BIGLITTLE(*--prodx,*prodx++) = pl;
- BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD128) /* use BNWORD128 */
- BNWORD128 p;
- t = BIGLITTLE(*--numx,*numx++);
- p = (BNWORD128)t * t;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD64)p;
- BIGLITTLE(*--prodx,*prodx++) = (BNWORD64)(p>>64);
-#else /* Use lbnMulN1_64 */
- t = BIGLITTLE(numx[-1],*numx);
- lbnMulN1_64(prodx, numx, 1, t);
- BIGLITTLE(--numx,numx++);
- BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
- }
- /* Then, shift right 1 bit */
- (void)lbnRshift_64(prod, 2*len, 1);
-
- /* Then, add in the off-diagonal sums */
- lenx = len;
- numx = num;
- prodx = prod;
- while (--lenx) {
- t = BIGLITTLE(*--numx,*numx++);
- BIGLITTLE(--prodx,prodx++);
- t = lbnMulAdd1_64(prodx, numx, lenx, t);
- lbnAdd1_64(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
- BIGLITTLE(--prodx,prodx++);
- }
-
- /* Shift it back up */
- lbnDouble_64(prod, 2*len);
-
- /* And set the low bit appropriately */
- BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_64 */
-
-/*
- * lbnNorm_64 - given a number, return a modified length such that the
- * most significant digit is non-zero. Zero-length input is okay.
- */
-#ifndef lbnNorm_64
-unsigned
-lbnNorm_64(BNWORD64 const *num, unsigned len)
-{
- BIGLITTLE(num -= len,num += len);
- while (len && BIGLITTLE(*num++,*--num) == 0)
- --len;
- return len;
-}
-#endif /* lbnNorm_64 */
-
-/*
- * lbnBits_64 - return the number of significant bits in the array.
- * It starts by normalizing the array. Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 64, and
- * subtracts off 64/2, 64/4, 64/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_64
-unsigned
-lbnBits_64(BNWORD64 const *num, unsigned len)
-{
- BNWORD64 t;
- unsigned i;
-
- len = lbnNorm_64(num, len);
- if (len) {
- t = BIGLITTLE(*(num-len),*(num+(len-1)));
- assert(t);
- len *= 64;
- i = 64/2;
- do {
- if (t >> i)
- t >>= i;
- else
- len -= i;
- } while ((i /= 2) != 0);
- }
- return len;
-}
-#endif /* lbnBits_64 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 64 bits, which a general 128-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_128
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_128 (128 > 0x20)
-#endif
-
-/*
- * Return (nh<<64|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set). If we have a double-width type, it's easy. If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_64
-#if defined(BNWORD128) && !BN_SLOW_DIVIDE_128
-BNWORD64
-lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d)
-{
- BNWORD128 n = (BNWORD128)nh << 64 | nl;
-
- /* Divisor must be normalized */
- assert(d >> (64-1) == 1);
-
- *q = n / d;
- return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth. Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- * _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- * - (qh * d)
- * -----------
- * rrrr rrrr nl.l
- * - (ql * d)
- * -----------
- * rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- * First, estimate a q digit so that nh/dh works. Subtracting qh*dh from
- * the (nh.h nh.l) list leaves a 1/2-word remainder r. Then compute the
- * low part of the subtractor, qh * dl. This also needs to be subtracted
- * from (nh.h nh.l nl.h) to get the final remainder. So we take the
- * remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- * try to subtract qh * dl from that. Since the remainder is 1/2-word
- * long, shifting and adding nl.h results in a single word r.
- * It is possible that the remainder we're working with, r, is less than
- * the product qh * dl, if we estimated qh too high. The estimation
- * technique can produce a qh that is too large (never too small), leading
- * to r which is too small. In that case, decrement the digit qh, add
- * shifted dh to r (to correct for that error), and subtract dl from the
- * product we're comparing r with. That's the "correct" way to do it, but
- * just adding dl to r instead of subtracting it from the product is
- * equivalent and a lot simpler. You just have to watch out for overflow.
- *
- * The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- * quotient ql.
- *
- * The various uses of 64/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 64/2 )
-#define lowhalf(x) ( (x) & (((BNWORD64)1 << 64/2)-1) )
-BNWORD64
-lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d)
-{
- BNWORD64 dh = highhalf(d), dl = lowhalf(d);
- BNWORD64 qh, ql, prod, r;
-
- /* Divisor must be normalized */
- assert((d >> (64-1)) == 1);
-
- /* Do first half-word of division */
- qh = nh / dh;
- r = nh % dh;
- prod = qh * dl;
-
- /*
- * Add next half-word of numerator to remainder and correct.
- * qh may be up to two too large.
- */
- r = (r << (64/2)) | highhalf(nl);
- if (r < prod) {
- --qh; r += d;
- if (r >= d && r < prod) {
- --qh; r += d;
- }
- }
- r -= prod;
-
- /* Do second half-word of division */
- ql = r / dh;
- r = r % dh;
- prod = ql * dl;
-
- r = (r << (64/2)) | lowhalf(nl);
- if (r < prod) {
- --ql; r += d;
- if (r >= d && r < prod) {
- --ql; r += d;
- }
- }
- r -= prod;
-
- *q = (qh << (64/2)) | ql;
-
- return r;
-}
-#endif
-#endif /* lbnDiv21_64 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long. It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient. The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_128, add a divnhalf_64 which uses 64-bit
- * dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- * instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_64
-BNWORD64
-lbnDiv1_64(BNWORD64 *q, BNWORD64 *rem, BNWORD64 const *n, unsigned len,
- BNWORD64 d)
-{
- unsigned shift;
- unsigned xlen;
- BNWORD64 r;
- BNWORD64 qhigh;
-
- assert(len > 0);
- assert(d);
-
- if (len == 1) {
- r = *n;
- *rem = r%d;
- return r/d;
- }
-
- shift = 0;
- r = d;
- xlen = 64/2;
- do {
- if (r >> xlen)
- r >>= xlen;
- else
- shift += xlen;
- } while ((xlen /= 2) != 0);
- assert((d >> (64-1-shift)) == 1);
- d <<= shift;
-
- BIGLITTLE(q -= len-1,q += len-1);
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r < d) {
- qhigh = 0;
- } else {
- qhigh = r/d;
- r %= d;
- }
-
- xlen = len;
- while (--xlen)
- r = lbnDiv21_64(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift) {
- d >>= shift;
- qhigh = (qhigh << shift) | lbnLshift_64(q, len-1, shift);
- BIGLITTLE(q[-1],*q) |= r/d;
- r %= d;
- }
- *rem = r;
-
- return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_64
-/* If there's a custom lbnMod21_64, no normalization needed */
-#ifdef lbnMod21_64
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD64 r;
-
- assert(len > 0);
-
- BIGLITTLE(n -= len,n += len);
-
- /* Try using a compare to avoid the first divide */
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
- while (--len)
- r = lbnMod21_64(r, BIGLITTLE(*n++,*--n), d);
-
- return r;
-}
-#elif defined(BNWORD128) && !BN_SLOW_DIVIDE_128
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
- BNWORD64 r;
-
- if (!--len)
- return BIGLITTLE(n[-1],n[0]) % d;
-
- BIGLITTLE(n -= len,n += len);
- r = BIGLITTLE(n[-1],n[0]);
-
- do {
- r = (BNWORD64)((((BNWORD128)r<<64) | BIGLITTLE(*n++,*--n)) % d);
- } while (--len);
-
- return r;
-}
-#elif 64 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 64/2 )
-#define lowhalf(x) ( (x) & ((1 << 64/2)-1) )
-#endif
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
- BNWORD64 r, x;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- while (--len) {
- x = BIGLITTLE(*n++,*--n);
- r = (r%d << 64/2) | highhalf(x);
- r = (r%d << 64/2) | lowhalf(x);
- }
-
- return r%d;
-}
-#else
-/* Default case - use lbnDiv21_64 */
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
- unsigned i, shift;
- BNWORD64 r;
- BNWORD64 q;
-
- assert(len > 0);
-
- shift = 0;
- r = d;
- i = 64;
- while (i /= 2) {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- }
- assert(d >> (64-1-shift) == 1);
- d <<= shift;
-
- BIGLITTLE(n -= len,n += len);
-
- r = BIGLITTLE(*n++,*--n);
- if (r >= d)
- r %= d;
-
- while (--len)
- r = lbnDiv21_64(&q, r, BIGLITTLE(*n++,*--n), d);
-
- /*
- * Final correction for shift - shift the quotient up "shift"
- * bits, and merge in the extra bits of quotient. Then reduce
- * the final remainder mod the real d.
- */
- if (shift)
- r %= d >> shift;
-
- return r;
-}
-#endif
-#endif /* lbnModQ_64 */
-
-/*
- * Reduce n mod d and return the quotient. That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long. To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor. WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction. This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount. This will produce the
- * correct quotient, and the remainder can be recovered by shifting
- * it back down the same number of bits. This may produce an overflow
- * word, but the word is always strictly less than the most significant
- * divisor word.
- * - Estimate the first quotient digit qhat:
- * - First take the top two words (one of which is the overflow) of the
- * dividend and divide by the top word of the divisor:
- * qhat = (nh,nm)/dh. This qhat is >= the correct quotient digit
- * and, since dh is normalized, it is at most two over.
- * - Second, correct by comparing the top three words. If
- * (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- * The second iteration can be simpler because there can't be a third.
- * The computation can be simplified by subtracting dh*qhat from
- * both sides, suitably shifted. This reduces the left side to
- * dl*qhat. On the right, (nh,nm)-dh*qhat is simply the
- * remainder r from (nh,nm)%dh, so the right is (r,nl).
- * This produces qhat that is almost always correct and at
- * most (prob ~ 2/2^64) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- * If there is a borrow, qhat was wrong, so decrement it
- * and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed. Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_64
-BNWORD64
-lbnDiv_64(BNWORD64 *q, BNWORD64 *n, unsigned nlen, BNWORD64 *d, unsigned dlen)
-{
- BNWORD64 nh,nm,nl; /* Top three words of the dividend */
- BNWORD64 dh,dl; /* Top two words of the divisor */
- BNWORD64 qhat; /* Extimate of quotient word */
- BNWORD64 r; /* Remainder from quotient estimate division */
- BNWORD64 qhigh; /* High word of quotient */
- unsigned i; /* Temp */
- unsigned shift; /* Bits shifted by normalization */
- unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul64_ppmm
- BNWORD64 t64;
-#elif defined(BNWORD128)
- BNWORD128 t128;
-#else /* use lbnMulN1_64 */
- BNWORD64 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
- assert(dlen);
- assert(nlen >= dlen);
-
- /*
- * Special cases for short divisors. The general case uses the
- * top top 2 digits of the divisor (d) to estimate a quotient digit,
- * so it breaks if there are fewer digits available. Thus, we need
- * special cases for a divisor of length 1. A divisor of length
- * 2 can have a *lot* of administrivia overhead removed removed,
- * so it's probably worth special-casing that case, too.
- */
- if (dlen == 1)
- return lbnDiv1_64(q, BIGLITTLE(n-1,n), n, nlen,
- BIGLITTLE(d[-1],d[0]));
-
-#if 0
- /*
- * @@@ This is not yet written... The general loop will do,
- * albeit less efficiently
- */
- if (dlen == 2) {
- /*
- * divisor two digits long:
- * use the 3/2 technique from Knuth, but we know
- * it's exact.
- */
- dh = BIGLITTLE(d[-1],d[0]);
- dl = BIGLITTLE(d[-2],d[1]);
- shift = 0;
- if ((sh & ((BNWORD64)1 << 64-1-shift)) == 0) {
- do {
- shift++;
- } while (dh & (BNWORD64)1<<64-1-shift) == 0);
- dh = dh << shift | dl >> (64-shift);
- dl <<= shift;
-
-
- }
-
-
- for (shift = 0; (dh & (BNWORD64)1 << 64-1-shift)) == 0; shift++)
- ;
- if (shift) {
- }
- dh = dh << shift | dl >> (64-shift);
- shift = 0;
- while (dh
- }
-#endif
-
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- assert(dh);
-
- /* Normalize the divisor */
- shift = 0;
- r = dh;
- i = 64/2;
- do {
- if (r >> i)
- r >>= i;
- else
- shift += i;
- } while ((i /= 2) != 0);
-
- nh = 0;
- if (shift) {
- lbnLshift_64(d, dlen, shift);
- dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
- nh = lbnLshift_64(n, nlen, shift);
- }
-
- /* Assert that dh is now normalized */
- assert(dh >> (64-1));
-
- /* Also get the second-most significant word of the divisor */
- dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
- /*
- * Adjust pointers: n to point to least significant end of first
- * first subtract, and q to one the most-significant end of the
- * quotient array.
- */
- BIGLITTLE(n -= qlen,n += qlen);
- BIGLITTLE(q -= qlen,q += qlen);
-
- /* Fetch the most significant stored word of the dividend */
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- /*
- * Compute the first digit of the quotient, based on the
- * first two words of the dividend (the most significant of which
- * is the overflow word h).
- */
- if (nh) {
- assert(nh < dh);
- r = lbnDiv21_64(&qhat, nh, nm, dh);
- } else if (nm >= dh) {
- qhat = nm/dh;
- r = nm % dh;
- } else { /* Quotient is zero */
- qhigh = 0;
- goto divloop;
- }
-
- /* Now get the third most significant word of the dividend */
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
- /*
- * Correct qhat, the estimate of quotient digit.
- * qhat can only be high, and at most two words high,
- * so the loop can be unrolled and abbreviated.
- */
-#ifdef mul64_ppmm
- mul64_ppmm(nm, t64, qhat, dl);
- if (nm > r || (nm == r && t64 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t64 < dl);
- t64 -= dl;
- if (nm > r || (nm == r && t64 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD128)
- t128 = (BNWORD128)qhat * dl;
- if (t128 > ((BNWORD128)r << 64) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) > dh) {
- t128 -= dl;
- if (t128 > ((BNWORD128)r << 64) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_64 */
- lbnMulN1_64(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /* Do the multiply and subtract */
- r = lbnMulSub1_64(n, d, dlen, qhat);
- /* If there was a borrow, add back once. */
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_64(n, d, dlen);
- qhat--;
- }
-
- /* Remember the first quotient digit. */
- qhigh = qhat;
-
- /* Now, the main division loop: */
-divloop:
- while (qlen--) {
-
- /* Advance n */
- nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
- BIGLITTLE(++n,--n);
- nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
- if (nh == dh) {
- qhat = ~(BNWORD64)0;
- /* Optimized computation of r = (nh,nm) - qhat * dh */
- r = nh + nm;
- if (r < nh)
- goto subtract;
- } else {
- assert(nh < dh);
- r = lbnDiv21_64(&qhat, nh, nm, dh);
- }
-
- nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul64_ppmm
- mul64_ppmm(nm, t64, qhat, dl);
- if (nm > r || (nm == r && t64 > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- nm -= (t64 < dl);
- t64 -= dl;
- if (nm > r || (nm == r && t64 > nl))
- qhat--;
- }
- }
-#elif defined(BNWORD128)
- t128 = (BNWORD128)qhat * dl;
- if (t128 > ((BNWORD128)r<<64) + nl) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t128 -= dl;
- if (t128 > ((BNWORD128)r << 64) + nl)
- qhat--;
- }
- }
-#else /* Use lbnMulN1_64 */
- lbnMulN1_64(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
- if (t2high > r || (t2high == r && t2low > nl)) {
- /* Decrement qhat and adjust comparison parameters */
- qhat--;
- if ((r += dh) >= dh) {
- t2high -= (t2low < dl);
- t2low -= dl;
- if (t2high > r || (t2high == r && t2low > nl))
- qhat--;
- }
- }
-#endif
-
- /*
- * As a point of interest, note that it is not worth checking
- * for qhat of 0 or 1 and installing special-case code. These
- * occur with probability 2^-64, so spending 1 cycle to check
- * for them is only worth it if we save more than 2^15 cycles,
- * and a multiply-and-subtract for numbers in the 1024-bit
- * range just doesn't take that long.
- */
-subtract:
- /*
- * n points to the least significant end of the substring
- * of n to be subtracted from. qhat is either exact or
- * one too large. If the subtract gets a borrow, it was
- * one too large and the divisor is added back in. It's
- * a dlen+1 word add which is guaranteed to produce a
- * carry out, so it can be done very simply.
- */
- r = lbnMulSub1_64(n, d, dlen, qhat);
- if (r > nh) { /* Borrow? */
- (void)lbnAddN_64(n, d, dlen);
- qhat--;
- }
- /* Store the quotient digit */
- BIGLITTLE(*q++,*--q) = qhat;
- }
- /* Tah dah! */
-
- if (shift) {
- lbnRshift_64(d, dlen, shift);
- lbnRshift_64(n, dlen, shift);
- }
-
- return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^64.
- *
- * This just performs Newton's iteration until it gets the
- * inverse. The initial estimate is always correct to 3 bits, and
- * sometimes 4. The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n. x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_64
-BNWORD64
-lbnMontInv1_64(BNWORD64 const x)
-{
- BNWORD64 y = x, z;
-
- assert(x & 1);
-
- while ((z = x*y) != 1)
- y *= 2 - z;
- return -y;
-}
-#endif /* !lbnMontInv1_64 */
-
-#if defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers. The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned mlen, BNWORD64 inv)
-{
- BNWORD128 x, y;
- BNWORD64 const *pm;
- BNWORD64 *pn;
- BNWORD64 t;
- unsigned carry;
- unsigned i, j;
-
- /* Special case of zero */
- if (!mlen)
- return;
-
- /* Pass 1 - compute Montgomery multipliers */
- /* First iteration can have certain simplifications. */
- t = BIGLITTLE(n[-1],n[0]);
- x = t;
- t *= inv;
- BIGLITTLE(n[-1], n[0]) = t;
- x += (BNWORD128)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
- assert((BNWORD64)x == 0);
- x = x >> 64;
-
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pn = n;
- pm = BIGLITTLE(mod-i-1,mod+i+1);
- for (j = 0; j < i; j++) {
- y = (BNWORD128)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pn == n-i, pn == n+i));
- y = t = BIGLITTLE(pn[-1], pn[0]);
- x += y;
- carry += (x < y);
- BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD64)x;
- assert(BIGLITTLE(pm == mod-1, pm == mod+1));
- y = (BNWORD128)t * BIGLITTLE(pm[0],pm[-1]);
- x += y;
- carry += (x < y);
- assert((BNWORD64)x == 0);
- x = x >> 64 | (BNWORD128)carry << 64;
- }
-
- BIGLITTLE(n -= mlen, n += mlen);
-
- /* Pass 2 - compute upper words and add to n */
- for (i = 1; i < mlen; i++) {
- carry = 0;
- pm = BIGLITTLE(mod-i,mod+i);
- pn = n;
- for (j = i; j < mlen; j++) {
- y = (BNWORD128)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
- x += y;
- carry += (x < y);
- }
- assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
- assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
- y = t = BIGLITTLE(*(n-i),*(n+i-1));
- x += y;
- carry += (x < y);
- BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD64)x;
- x = (x >> 64) | (BNWORD128)carry << 64;
- }
-
- /* Last round of second half, simplified. */
- t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
- x += t;
- BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD64)x;
- carry = (unsigned)(x >> 64);
-
- while (carry)
- carry -= lbnSubN_64(n, mod, mlen);
- while (lbnCmp_64(n, mod, mlen) >= 0)
- (void)lbnSubN_64(n, mod, mlen);
-}
-#define lbnMontReduce_64 lbnMontReduce_64
-#endif
-
-/*
- * Montgomery reduce n, modulo mod. This reduces modulo mod and divides by
- * 2^(64*mlen). Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_64.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction. What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift. In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(64*mlen). Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc. Note that:
- * - The Montgomery form of a number depends on the modulus m.
- * A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- * no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- * M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R. The problem
- * is to divide out the excess factor of R, modulo m as well as to
- * reduce to the given length mlen. It turns out that this can be
- * done *faster* than a normal divide, which is where the speedup
- * in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced. Choosing q is tricky
- * and involved (just look at lbnDiv_64 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced. This multiple is chosen to make the
- * low-order part of the number come out to zero. This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R. Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication. To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- *
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_64
-void
-lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned const mlen,
- BNWORD64 inv)
-{
- BNWORD64 t;
- BNWORD64 c = 0;
- unsigned len = mlen;
-
- /* inv must be the negative inverse of mod's least significant word */
- assert((BNWORD64)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD64)-1);
-
- assert(len);
-
- do {
- t = lbnMulAdd1_64(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
- c += lbnAdd1_64(BIGLITTLE(n-mlen,n+mlen), len, t);
- BIGLITTLE(--n,++n);
- } while (--len);
-
- /*
- * All that adding can cause an overflow past the modulus size,
- * but it's unusual, and never by much, so a subtraction loop
- * is the right way to deal with it.
- * This subtraction happens infrequently - I've only ever seen it
- * invoked once per reduction, and then just under 22.5% of the time.
- */
- while (c)
- c -= lbnSubN_64(n, mod, mlen);
- while (lbnCmp_64(n, mod, mlen) >= 0)
- (void)lbnSubN_64(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_64 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_64
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod". "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^64.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_64(prod, n1, n2, mod, len, inv) \
- (lbnMulX_64(prod, n1, n2, len), lbnMontReduce_64(prod, mod, len, inv))
-#endif /* !lbnMontMul_64 */
-
-#ifndef lbnMontSquare_64
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod". "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^64.
- * This uses numbers in Montgomery form. Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_64(prod, n, mod, len, inv) \
- (lbnSquare_64(prod, n, len), lbnMontReduce_64(prod, mod, len, inv))
-
-#endif /* !lbnMontSquare_64 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_64(BNWORD64 *n, unsigned nlen, BNWORD64 *mod, unsigned mlen)
-{
- /* Move n up "mlen" words */
- lbnCopy_64(BIGLITTLE(n-mlen,n+mlen), n, nlen);
- lbnZero_64(n, mlen);
- /* Do the division - dump the quotient in the high-order words */
- (void)lbnDiv_64(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form. Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_64(BNWORD64 *n, BNWORD64 *mod, unsigned len)
-{
- /* Zero the high words of n */
- lbnZero_64(BIGLITTLE(n-len,n+len), len);
- lbnMontReduce_64(n, mod, len, lbnMontInv1_64(mod[BIGLITTLE(-1,0)]));
- /* Move n down len words */
- lbnCopy_64(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k. See the comment in bnExpMod_64 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation. To minimize
- * the sum, k must vary with e. The optimal window sizes vary with the
- * exponent length. Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 64 do not appear in this table. It should be
- * ignored.)
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 8 bits, k=2 (3.333333) < k=1 (3.500000)
- * At e = 1_6 bits, k=2 (6.000000) is best
- * At e = 26 bits, k=3 (9.250000) < k=2 (9.333333)
- * At e = 3_2 bits, k=3 (10.750000) is best
- * At e = 6_4 bits, k=3 (18.750000) is best
- * At e = 82 bits, k=4 (23.200000) < k=3 (23.250000)
- * At e = 128 bits, k=4 (3_2.400000) is best
- * At e = 242 bits, k=5 (55.1_66667) < k=4 (55.200000)
- * At e = 256 bits, k=5 (57.500000) is best
- * At e = 512 bits, k=5 (100.1_66667) is best
- * At e = 674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation. The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2. For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5. Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings. It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case. Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all. Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e = 1 bits, k=1 (0.000000) is best
- * At e = 2 bits, k=1 (0.500000) is best
- * At e = 4 bits, k=1 (1.500000) is best
- * At e = 6 bits, k=2 (2.437500) < k=1 (2.500000)
- * At e = 8 bits, k=2 (3.109375) is best
- * At e = 1_6 bits, k=2 (5.777771) is best
- * At e = 24 bits, k=3 (8.437629) < k=2 (8.444444)
- * At e = 3_2 bits, k=3 (10.437492) is best
- * At e = 6_4 bits, k=3 (18.437500) is best
- * At e = 81 bits, k=4 (22.6_40000) < k=3 (22.687500)
- * At e = 128 bits, k=4 (3_2.040000) is best
- * At e = 241 bits, k=5 (54.611111) < k=4 (54.6_40000)
- * At e = 256 bits, k=5 (57.111111) is best
- * At e = 512 bits, k=5 (99.777778) is best
- * At e = 673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794. Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here. It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables. Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1. Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW 7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
- 5, 23, 80, 240, 672, 1792, (unsigned)-1
-/* 7, 25, 81, 241, 673, 1793, (unsigned)-1 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible! This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it. The following patterns
- * apply to a 3-bit window (k = 3):
- * To append 0: square
- * To append 1: square, multiply by n^1
- * To append 10: square, multiply by n^1, square
- * To append 11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time. Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/64 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes. There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits. (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it. We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away. Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings. 1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1. The average of these is 1. Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies. (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated. Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_64(BNWORD64 *result, BNWORD64 const *n, unsigned nlen,
- BNWORD64 const *e, unsigned elen, BNWORD64 *mod, unsigned mlen)
-{
- BNWORD64 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n */
- unsigned ebits; /* Exponent bits */
- unsigned wbits; /* Window size */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD64 bitpos; /* Mask of current look-ahead bit */
- unsigned buf; /* Buffer of exponent bits */
- unsigned multpos; /* Where to do pending multiply */
- BNWORD64 const *mult; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD64 *a, *b; /* Working buffers/accumulators */
- BNWORD64 *t; /* Pointer into the working buffers */
- BNWORD64 inv; /* mod^-1 modulo 2^64 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(nlen <= mlen);
-
- /* First, a couple of trivial cases. */
- elen = lbnNorm_64(e, elen);
- if (!elen) {
- /* x ^ 0 == 1 */
- lbnZero_64(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- ebits = lbnBits_64(e, elen);
- if (ebits == 1) {
- /* x ^ 1 == x */
- if (n != result)
- lbnCopy_64(result, n, nlen);
- if (mlen > nlen)
- lbnZero_64(BIGLITTLE(result-nlen,result+nlen),
- mlen-nlen);
- return 0;
- }
-
- /* Okay, now move the exponent pointer to the most-significant word */
- e = BIGLITTLE(e-elen, e+elen-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- wbits = 0;
- while (ebits > bnExpModThreshTable[wbits])
- wbits++;
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD64, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD64, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << wbits;
-
- /* We have the result buffer available, so use it. */
- table[0] = result;
-
- /*
- * Okay, we now have a minimal-sized table - expand it.
- * This is allowed to fail! If so, scale back the table size
- * and proceed.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD64, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table[i] = t;
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- wbits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask)
- LBNFREE(table[i], mlen);
-
- /* Okay, fill in the table */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n to Montgomery form */
-
- /* Move n up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_64(t, n, nlen);
- lbnZero_64(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_64(t, a, mlen+nlen, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_64(table[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_64(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_64(a, t, table[i-1], mod, mlen, inv);
- lbnCopy_64(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* We might use b = n^2 later... */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD64)1 << ((ebits-1) & (64-1)); /* Initialize mask */
-
- /* This should point to the msbit of e */
- assert((*e & bitpos) != 0);
-
- /*
- * Pre-load the window. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e in here.
- *
- * The read-ahead is controlled by elen and the bitpos mask.
- * Note that this is *ahead* of ebits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two wbits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- */
- buf = 0;
- for (i = 0; i <= wbits; i++) {
- buf = (buf << 1) | ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD64)1 << (64-1);
- elen--;
- }
- }
- assert(buf & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- multpos = ebits; /* A NULL value */
- mult = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- ebits--; /* Start processing the first bit... */
- isone = 1;
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf is set, and
- * - We have the extra value n^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf & tblmask);
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (multpos == ebits)
- isone = 0;
-
- /*
- * At this point, the buffer (which is the high half of b) holds
- * either 1 (implicitly, as the "isone" flag is set), or n^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the window
- * - If the most-significant bit of the window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffer
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- ebits--;
-
- /* Advance the window */
- assert(buf < tblmask);
- buf <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by ebits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (elen) {
- buf |= ((*e & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e++,e--);
- bitpos = (BNWORD64)1 << (64-1);
- elen--;
- }
- }
-
- /* Examine the window for pending multiplies */
- if (buf & tblmask) {
- multpos = ebits - wbits;
- while ((buf & 1) == 0) {
- buf >>= 1;
- multpos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(multpos <= ebits);
- mult = table[buf>>1];
- buf = 0;
- }
-
- /* If we have a pending multiply, do it */
- if (ebits == multpos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_64(t, mult, mlen);
- isone = 0;
- } else {
- lbnMontMul_64(a, t, mult, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!ebits)
- break;
-
- /* Square the input */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_64(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_64(b, t, mlen);
- lbnZero_64(t, mlen);
- lbnMontReduce_64(b, mod, mlen, inv);
- lbnCopy_64(result, t, mlen);
- /*
- * Clean up - free intermediate storage.
- * Do NOT free table[0], which is the result
- * buffer.
- */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- while (--tblmask)
- LBNFREE(table[tblmask], mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1). When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place. Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future. But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading. The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_64(BNWORD64 *result,
- BNWORD64 const *n1, unsigned n1len,
- BNWORD64 const *e1, unsigned e1len,
- BNWORD64 const *n2, unsigned n2len,
- BNWORD64 const *e2, unsigned e2len,
- BNWORD64 *mod, unsigned mlen)
-{
- BNWORD64 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n1 */
- BNWORD64 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
- /* Table of odd powers of n2 */
- unsigned e1bits, e2bits; /* Exponent bits */
- unsigned w1bits, w2bits; /* Window sizes */
- unsigned tblmask; /* Mask of exponentiation window */
- BNWORD64 bitpos; /* Mask of current look-ahead bit */
- unsigned buf1, buf2; /* Buffer of exponent bits */
- unsigned mult1pos, mult2pos; /* Where to do pending multiply */
- BNWORD64 const *mult1, *mult2; /* What to multiply by */
- unsigned i; /* Loop counter */
- int isone; /* Flag: accum. is implicitly one */
- BNWORD64 *a, *b; /* Working buffers/accumulators */
- BNWORD64 *t; /* Pointer into the working buffers */
- BNWORD64 inv; /* mod^-1 modulo 2^64 */
- int y; /* bnYield() result */
-
- assert(mlen);
- assert(n1len <= mlen);
- assert(n2len <= mlen);
-
- /* First, a couple of trivial cases. */
- e1len = lbnNorm_64(e1, e1len);
- e2len = lbnNorm_64(e2, e2len);
-
- /* Ensure that the first exponent is the longer */
- e1bits = lbnBits_64(e1, e1len);
- e2bits = lbnBits_64(e2, e2len);
- if (e1bits < e2bits) {
- i = e1len; e1len = e2len; e2len = i;
- i = e1bits; e1bits = e2bits; e2bits = i;
- t = (BNWORD64 *)n1; n1 = n2; n2 = t;
- t = (BNWORD64 *)e1; e1 = e2; e2 = t;
- }
- assert(e1bits >= e2bits);
-
- /* Handle a trivial case */
- if (!e2len)
- return lbnExpMod_64(result, n1, n1len, e1, e1len, mod, mlen);
- assert(e2bits);
-
- /* The code below fucks up if the exponents aren't at least 2 bits */
- if (e1bits == 1) {
- assert(e2bits == 1);
-
- LBNALLOC(a, BNWORD64, n1len+n2len);
- if (!a)
- return -1;
-
- lbnMul_64(a, n1, n1len, n2, n2len);
- /* Do a direct modular reduction */
- if (n1len + n2len >= mlen)
- (void)lbnDiv_64(a+mlen, a, n1len+n2len, mod, mlen);
- lbnCopy_64(result, a, mlen);
- LBNFREE(a, n1len+n2len);
- return 0;
- }
-
- /* Okay, now move the exponent pointers to the most-significant word */
- e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
- e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
- /* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
- w1bits = 0;
- while (e1bits > bnExpModThreshTable[w1bits])
- w1bits++;
- w2bits = 0;
- while (e2bits > bnExpModThreshTable[w2bits])
- w2bits++;
-
- assert(w1bits >= w2bits);
-
- /* Allocate working storage: two product buffers and the tables. */
- LBNALLOC(a, BNWORD64, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD64, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert to the appropriate table size: tblmask = 1<<(k-1) */
- tblmask = 1u << w1bits;
- /* Use buf2 for its size, temporarily */
- buf2 = 1u << w2bits;
-
- LBNALLOC(t, BNWORD64, mlen);
- if (!t) {
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return -1;
- }
- table1[0] = t;
- table2[0] = result;
-
- /*
- * Okay, we now have some minimal-sized tables - expand them.
- * This is allowed to fail! If so, scale back the table sizes
- * and proceed. We allocate both tables at the same time
- * so if it fails partway through, they'll both be a reasonable
- * size rather than one huge and one tiny.
- * When i passes buf2 (the number of entries in the e2 window,
- * which may be less than the number of entries in the e1 window),
- * stop allocating e2 space.
- */
- for (i = 1; i < tblmask; i++) {
- LBNALLOC(t, BNWORD64, mlen);
- if (!t) /* Out of memory! Quit the loop. */
- break;
- table1[i] = t;
- if (i < buf2) {
- LBNALLOC(t, BNWORD64, mlen);
- if (!t) {
- LBNFREE(table1[i], mlen);
- break;
- }
- table2[i] = t;
- }
- }
-
- /* If we stopped, with i < tblmask, shrink the tables appropriately */
- while (tblmask > i) {
- w1bits--;
- tblmask >>= 1;
- }
- /* Free up our overallocations */
- while (--i > tblmask) {
- if (i < buf2)
- LBNFREE(table2[i], mlen);
- LBNFREE(table1[i], mlen);
- }
- /* And shrink the second window too, if needed */
- if (w2bits > w1bits) {
- w2bits = w1bits;
- buf2 = tblmask;
- }
-
- /*
- * From now on, use the w2bits variable for the difference
- * between w1bits and w2bits.
- */
- w2bits = w1bits-w2bits;
-
- /* Okay, fill in the tables */
-
- /* Compute the necessary modular inverse */
- inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- /* Convert n1 to Montgomery form */
-
- /* Move n1 up "mlen" words into a */
- t = BIGLITTLE(a-mlen, a+mlen);
- lbnCopy_64(t, n1, n1len);
- lbnZero_64(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_64(t, a, mlen+n1len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_64(table1[0], a, mlen);
-
- /* Square a into b */
- lbnMontSquare_64(b, a, mod, mlen, inv);
-
- /* Use high half of b to initialize the first table */
- t = BIGLITTLE(b-mlen, b+mlen);
- for (i = 1; i < tblmask; i++) {
- lbnMontMul_64(a, t, table1[i-1], mod, mlen, inv);
- lbnCopy_64(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* Convert n2 to Montgomery form */
-
- t = BIGLITTLE(a-mlen, a+mlen);
- /* Move n2 up "mlen" words into a */
- lbnCopy_64(t, n2, n2len);
- lbnZero_64(a, mlen);
- /* Do the division - lose the quotient into the high-order words */
- (void)lbnDiv_64(t, a, mlen+n2len, mod, mlen);
- /* Copy into first table entry */
- lbnCopy_64(table2[0], a, mlen);
-
- /* Square it into a */
- lbnMontSquare_64(a, table2[0], mod, mlen, inv);
- /* Copy to b, low half */
- lbnCopy_64(b, t, mlen);
-
- /* Use b to initialize the second table */
- for (i = 1; i < buf2; i++) {
- lbnMontMul_64(a, b, table2[i-1], mod, mlen, inv);
- lbnCopy_64(table2[i], t, mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /*
- * Okay, a recap: at this point, the low part of b holds
- * n2^2, the high part holds n1^2, and the tables are
- * initialized with the odd powers of n1 and n2 from 1
- * through 2*tblmask-1 and 2*buf2-1.
- *
- * We might use those squares in b later, or we might not.
- */
-
- /* Initialze the fetch pointer */
- bitpos = (BNWORD64)1 << ((e1bits-1) & (64-1)); /* Initialize mask */
-
- /* This should point to the msbit of e1 */
- assert((*e1 & bitpos) != 0);
-
- /*
- * Pre-load the windows. Becuase the window size is
- * never larger than the exponent size, there is no need to
- * detect running off the end of e1 in here.
- *
- * The read-ahead is controlled by e1len and the bitpos mask.
- * Note that this is *ahead* of e1bits, which tracks the
- * most significant end of the window. The purpose of this
- * initialization is to get the two w1bits+1 bits apart,
- * like they should be.
- *
- * Note that bitpos and e1len together keep track of the
- * lookahead read pointer in the exponent that is used here.
- * e2len is not decremented, it is only ever compared with
- * e1len as *that* is decremented.
- */
- buf1 = buf2 = 0;
- for (i = 0; i <= w1bits; i++) {
- buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD64)1 << (64-1);
- e1len--;
- }
- }
- assert(buf1 & tblmask);
-
- /*
- * Set the pending multiply positions to a location that will
- * never be encountered, thus ensuring that nothing will happen
- * until the need for a multiply appears and one is scheduled.
- */
- mult1pos = mult2pos = e1bits; /* A NULL value */
- mult1 = mult2 = 0; /* Force a crash if we use these */
-
- /*
- * Okay, now begins the real work. The first step is
- * slightly magic, so it's done outside the main loop,
- * but it's very similar to what's inside.
- */
- isone = 1; /* Buffer is implicitly 1, so replace * by copy */
- e1bits--; /* Start processing the first bit... */
-
- /*
- * This is just like the multiply in the loop, except that
- * - We know the msbit of buf1 is set, and
- * - We have the extra value n1^2 floating around.
- * So, do the usual computation, and if the result is that
- * the buffer should be multiplied by n1^1 immediately
- * (which we'd normally then square), we multiply it
- * (which reduces to a copy, which reduces to setting a flag)
- * by n1^2 and skip the squaring. Thus, we do the
- * multiply and the squaring in one step.
- */
- assert(buf1 & tblmask);
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
-
- /* Special case: use already-computed value sitting in buffer */
- if (mult1pos == e1bits)
- isone = 0;
-
- /*
- * The first multiply by a power of n2. Similar, but
- * we might not even want to schedule a multiply if e2 is
- * shorter than e1, and the window might be shorter so
- * we have to leave the low w2bits bits alone.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
-
- if (mult2pos == e1bits) {
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- lbnCopy_64(t, b, mlen); /* Copy low to high */
- isone = 0;
- } else {
- lbnMontMul_64(a, t, b, mod, mlen, inv);
- t = a; a = b; b = t;
- }
- }
- }
-
- /*
- * At this point, the buffer (which is the high half of b)
- * holds either 1 (implicitly, as the "isone" flag is set),
- * n1^2, n2^2 or n1^2 * n2^2.
- */
-
- /*
- * The main loop. The procedure is:
- * - Advance the windows
- * - If the most-significant bit of a window is set,
- * schedule a multiply for the appropriate time in the
- * future (may be immediately)
- * - Perform any pending multiples
- * - Check for termination
- * - Square the buffers
- *
- * At any given time, the acumulated product is held in
- * the high half of b.
- */
- for (;;) {
- e1bits--;
-
- /* Advance the windows */
- assert(buf1 < tblmask);
- buf1 <<= 1;
- assert(buf2 < tblmask);
- buf2 <<= 1;
- /*
- * This reads ahead of the current exponent position
- * (controlled by e1bits), so we have to be able to read
- * past the lsb of the exponents without error.
- */
- if (e1len) {
- buf1 |= ((*e1 & bitpos) != 0);
- if (e1len <= e2len)
- buf2 |= ((*e2 & bitpos) != 0);
- bitpos >>= 1;
- if (!bitpos) {
- BIGLITTLE(e1++,e1--);
- if (e1len <= e2len)
- BIGLITTLE(e2++,e2--);
- bitpos = (BNWORD64)1 << (64-1);
- e1len--;
- }
- }
-
- /* Examine the first window for pending multiplies */
- if (buf1 & tblmask) {
- mult1pos = e1bits - w1bits;
- while ((buf1 & 1) == 0) {
- buf1 >>= 1;
- mult1pos++;
- }
- /* Intermediates can wrap, but final must NOT */
- assert(mult1pos <= e1bits);
- mult1 = table1[buf1>>1];
- buf1 = 0;
- }
-
- /*
- * Examine the second window for pending multiplies.
- * Window 2 can be smaller than window 1, but we
- * keep the same number of bits in buf2, so we need
- * to ignore any low-order bits in the buffer when
- * computing what to multiply by, and recompute them
- * later.
- */
- if (buf2 & tblmask) {
- /* Remember low-order bits for later */
- i = buf2 & ((1u << w2bits) - 1);
- buf2 >>= w2bits;
- mult2pos = e1bits - w1bits + w2bits;
- while ((buf2 & 1) == 0) {
- buf2 >>= 1;
- mult2pos++;
- }
- assert(mult2pos <= e1bits);
- mult2 = table2[buf2>>1];
- buf2 = i;
- }
-
-
- /* If we have a pending multiply for e1, do it */
- if (e1bits == mult1pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_64(t, mult1, mlen);
- isone = 0;
- } else {
- lbnMontMul_64(a, t, mult1, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* If we have a pending multiply for e2, do it */
- if (e1bits == mult2pos) {
- /* Multiply by the table entry remembered previously */
- t = BIGLITTLE(b-mlen, b+mlen);
- if (isone) {
- /* Multiply by 1 is a trivial case */
- lbnCopy_64(t, mult2, mlen);
- isone = 0;
- } else {
- lbnMontMul_64(a, t, mult2, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
- }
-
- /* Are we done? */
- if (!e1bits)
- break;
-
- /* Square the buffer */
- if (!isone) {
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnMontSquare_64(a, t, mod, mlen, inv);
- /* Swap a and b */
- t = a; a = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- } /* for (;;) */
-
- assert(!isone);
- assert(!buf1);
- assert(!buf2);
-
- /* DONE! */
-
- /* Convert result out of Montgomery form */
- t = BIGLITTLE(b-mlen, b+mlen);
- lbnCopy_64(b, t, mlen);
- lbnZero_64(t, mlen);
- lbnMontReduce_64(b, mod, mlen, inv);
- lbnCopy_64(result, t, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- buf2 = tblmask >> w2bits;
- while (--tblmask) {
- if (tblmask < buf2)
- LBNFREE(table2[tblmask], mlen);
- LBNFREE(table1[tblmask], mlen);
- }
- t = table1[0];
- LBNFREE(t, mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-/*
- * 2^exp (mod mod). This is an optimized version for use in Fermat
- * tests. The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_64(BNWORD64 *n, BNWORD64 const *exp, unsigned elen,
- BNWORD64 *mod, unsigned mlen)
-{
- unsigned e; /* Copy of high words of the exponent */
- unsigned bits; /* Assorted counter of bits */
- BNWORD64 const *bitptr;
- BNWORD64 bitword, bitpos;
- BNWORD64 *a, *b, *a1;
- BNWORD64 inv;
- int y; /* Result of bnYield() */
-
- assert(mlen);
-
- bitptr = BIGLITTLE(exp-elen, exp+elen-1);
- bitword = *bitptr;
- assert(bitword);
-
- /* Clear n for future use. */
- lbnZero_64(n, mlen);
-
- bits = lbnBits_64(exp, elen);
-
- /* First, a couple of trivial cases. */
- if (bits <= 1) {
- /* 2 ^ 0 == 1, 2 ^ 1 == 2 */
- BIGLITTLE(n[-1],n[0]) = (BNWORD64)1<<elen;
- return 0;
- }
-
- /* Set bitpos to the most significant bit */
- bitpos = (BNWORD64)1 << ((bits-1) & (64-1));
-
- /* Now, count the bits in the modulus. */
- bits = lbnBits_64(mod, mlen);
- assert(bits > 1); /* a 1-bit modulus is just stupid... */
-
- /*
- * We start with 1<<e, where "e" is as many high bits of the
- * exponent as we can manage without going over the modulus.
- * This first loop finds "e".
- */
- e = 1;
- while (elen) {
- /* Consume the first bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break;
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD64)1<<(64-1);
- }
- e = (e << 1) | ((bitpos & bitword) != 0);
- if (e >= bits) { /* Overflow! Back out. */
- e >>= 1;
- break;
- }
- }
- /*
- * The bit in "bitpos" being examined by the bit buffer has NOT
- * been consumed yet. This may be past the end of the exponent,
- * in which case elen == 1.
- */
-
- /* Okay, now, set bit "e" in n. n is already zero. */
- inv = (BNWORD64)1 << (e & (64-1));
- e /= 64;
- BIGLITTLE(n[-e-1],n[e]) = inv;
- /*
- * The effective length of n in words is now "e+1".
- * This is used a little bit later.
- */
-
- if (!elen)
- return 0; /* That was easy! */
-
- /*
- * We have now processed the first few bits. The next step
- * is to convert this to Montgomery form for further squaring.
- */
-
- /* Allocate working storage: two product buffers */
- LBNALLOC(a, BNWORD64, 2*mlen);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD64, 2*mlen);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_64(inv);
- /* Move n (length e+1, remember?) up "mlen" words into b */
- /* Note that we lie about a1 for a bit - it's pointing to b */
- a1 = BIGLITTLE(b-mlen,b+mlen);
- lbnCopy_64(a1, n, e+1);
- lbnZero_64(b, mlen);
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_64(a1, b, mlen+e+1, mod, mlen);
- /*
- * Now do the first squaring and modular reduction to put
- * the number up in a1 where it belongs.
- */
- lbnMontSquare_64(a, b, mod, mlen, inv);
- /* Fix up a1 to point to where it should go. */
- a1 = BIGLITTLE(a-mlen,a+mlen);
-
- /*
- * Okay, now, a1 holds the number being accumulated, and
- * b is a scratch register. Start working:
- */
- for (;;) {
- /*
- * Is the bit set? If so, double a1 as well.
- * A modular doubling like this is very cheap.
- */
- if (bitpos & bitword) {
- /*
- * Double the number. If there was a carry out OR
- * the result is greater than the modulus, subract
- * the modulus.
- */
- if (lbnDouble_64(a1, mlen) ||
- lbnCmp_64(a1, mod, mlen) > 0)
- (void)lbnSubN_64(a1, mod, mlen);
- }
-
- /* Advance to the next exponent bit */
- bitpos >>= 1;
- if (!bitpos) {
- if (!--elen)
- break; /* Done! */
- bitword = BIGLITTLE(*++bitptr,*--bitptr);
- bitpos = (BNWORD64)1<<(64-1);
- }
-
- /*
- * The elen/bitword/bitpos bit buffer is known to be
- * non-empty, i.e. there is at least one more unconsumed bit.
- * Thus, it's safe to square the number.
- */
- lbnMontSquare_64(b, a1, mod, mlen, inv);
- /* Rename result (in b) back to a (a1, really). */
- a1 = b; b = a; a = a1;
- a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- goto yield;
-#endif
- }
-
- /* DONE! Just a little bit of cleanup... */
-
- /*
- * Convert result out of Montgomery form... this is
- * just a Montgomery reduction.
- */
- lbnCopy_64(a, a1, mlen);
- lbnZero_64(a1, mlen);
- lbnMontReduce_64(a, mod, mlen, inv);
- lbnCopy_64(n, a1, mlen);
-
- /* Clean up - free intermediate storage */
- y = 0;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y; /* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_64(BNWORD64 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD64 t = 0; /* Needed to shut up uninitialized var warnings */
- unsigned shift;
-
- lsbyte += buflen;
-
- shift = (8 * lsbyte) % 64;
- lsbyte /= (64/8); /* Convert to word offset */
- BIGLITTLE(n -= lsbyte, n += lsbyte);
-
- if (shift)
- t = BIGLITTLE(n[-1],n[0]);
-
- while (buflen--) {
- if (!shift) {
- t = BIGLITTLE(*n++,*--n);
- shift = 64;
- }
- shift -= 8;
- *buf++ = (unsigned char)(t>>shift);
- }
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_64(BNWORD64 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD64 t = 0; /* Shut up uninitialized varibale warnings */
-
- lsbyte += buflen;
-
- BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (64/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 64;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *buf++;
- if ((--lsbyte % (64/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 64;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD64)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length. I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_64(BNWORD64 const *n, unsigned char *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD64 t = 0; /* Needed to shut up uninitialized var warnings */
-
- BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
- if (lsbyte % (64/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte % (64/8)) * 8 ;
- }
-
- while (buflen--) {
- if ((lsbyte++ % (64/8)) == 0)
- t = BIGLITTLE(*--n,*n++);
- *buf++ = (unsigned char)t;
- t >>= 8;
- }
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough. This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right. Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_64(BNWORD64 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen)
-{
- BNWORD64 t = 0; /* Shut up uninitialized varibale warnings */
-
- /* Move to most-significant end */
- lsbyte += buflen;
- buf += buflen;
-
- BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
- /* Load up leading odd bytes */
- if (lsbyte % (64/8)) {
- t = BIGLITTLE(*--n,*n++);
- t >>= (lsbyte * 8) % 64;
- }
-
- /* The main loop - merge into t, storing at each word boundary. */
- while (buflen--) {
- t = (t << 8) | *--buf;
- if ((--lsbyte % (64/8)) == 0)
- BIGLITTLE(*n++,*--n) = t;
- }
-
- /* Merge odd bytes in t into last word */
- lsbyte = (lsbyte * 8) % 64;
- if (lsbyte) {
- t <<= lsbyte;
- t |= (((BNWORD64)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
- BIGLITTLE(n[0],n[-1]) = t;
- }
-
- return;
-}
-
-#ifdef DEADCODE /* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "64/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_64(BNWORD64 *a, unsigned char const *b, unsigned blen)
-{
- BNWORD64 t;
- unsigned alen = (blen + (64/8-1))/(64/8);
- BIGLITTLE(a -= alen, a += alen);
-
- while (blen) {
- t = 0;
- do {
- t = t << 8 | *b++;
- } while (--blen & (64/8-1));
- BIGLITTLE(*a++,*--a) = t;
- }
- return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b. Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash. The return value
- * indicates which: 0 for a, and 1 for b. The length of the retult is
- * returned in rlen. Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_64(BNWORD64 *a, unsigned alen, BNWORD64 *b, unsigned blen,
- unsigned *rlen)
-{
-#if BNYIELD
- int y;
-#endif
- assert(alen >= blen);
-
- while (blen != 0) {
- (void)lbnDiv_64(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- alen = lbnNorm_64(a, blen);
- if (alen == 0) {
- *rlen = blen;
- return 1;
- }
- (void)lbnDiv_64(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- blen = lbnNorm_64(b, alen);
-#if BNYIELD
- if (bnYield && (y = bnYield()) < 0)
- return y;
-#endif
- }
- *rlen = alen;
- return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1. Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod". It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_64(BNWORD64 *a, unsigned alen, BNWORD64 const *mod, unsigned mlen)
-{
- BNWORD64 *b; /* Hold a copy of mod during GCD reduction */
- BNWORD64 *p; /* Temporary for products added to t0 and t1 */
- BNWORD64 *t0, *t1; /* Inverse accumulators */
- BNWORD64 cy;
- unsigned blen, t0len, t1len, plen;
- int y;
-
- alen = lbnNorm_64(a, alen);
- if (!alen)
- return 1; /* No inverse */
-
- mlen = lbnNorm_64(mod, mlen);
-
- assert (alen <= mlen);
-
- /* Inverse of 1 is 1 */
- if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
- lbnZero_64(BIGLITTLE(a-alen,a+alen), mlen-alen);
- return 0;
- }
-
- /* Allocate a pile of space */
- LBNALLOC(b, BNWORD64, mlen+1);
- if (b) {
- /*
- * Although products are guaranteed to always be less than the
- * modulus, it can involve multiplying two 3-word numbers to
- * get a 5-word result, requiring a 6th word to store a 0
- * temporarily. Thus, mlen + 1.
- */
- LBNALLOC(p, BNWORD64, mlen+1);
- if (p) {
- LBNALLOC(t0, BNWORD64, mlen);
- if (t0) {
- LBNALLOC(t1, BNWORD64, mlen);
- if (t1)
- goto allocated;
- LBNFREE(t0, mlen);
- }
- LBNFREE(p, mlen+1);
- }
- LBNFREE(b, mlen+1);
- }
- return -1;
-
-allocated:
-
- /* Set t0 to 1 */
- t0len = 1;
- BIGLITTLE(t0[-1],t0[0]) = 1;
-
- /* b = mod */
- lbnCopy_64(b, mod, mlen);
- /* blen = mlen (implicitly) */
-
- /* t1 = b / a; b = b % a */
- cy = lbnDiv_64(t1, b, mlen, a, alen);
- *(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
- t1len = lbnNorm_64(t1, mlen-alen+1);
- blen = lbnNorm_64(b, alen);
-
- /* while (b > 1) */
- while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD64)1) {
- /* q = a / b; a = a % b; */
- if (alen < blen || (alen == blen && lbnCmp_64(a, a, alen) < 0))
- assert(0);
- cy = lbnDiv_64(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
- *(BIGLITTLE(a-alen-1,a+alen)) = cy;
- plen = lbnNorm_64(BIGLITTLE(a-blen,a+blen), alen-blen+1);
- assert(plen);
- alen = lbnNorm_64(a, blen);
- if (!alen)
- goto failure; /* GCD not 1 */
-
- /* t0 += q * t1; */
- assert(plen+t1len <= mlen+1);
- lbnMul_64(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
- plen = lbnNorm_64(p, plen + t1len);
- assert(plen <= mlen);
- if (plen > t0len) {
- lbnZero_64(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
- t0len = plen;
- }
- cy = lbnAddN_64(t0, p, plen);
- if (cy) {
- if (t0len > plen) {
- cy = lbnAdd1_64(BIGLITTLE(t0-plen,t0+plen),
- t0len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
- t0len++;
- }
- }
-
- /* if (a <= 1) return a ? t0 : FAIL; */
- if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD64)1) {
- if (alen == 0)
- goto failure; /* FAIL */
- assert(t0len <= mlen);
- lbnCopy_64(a, t0, t0len);
- lbnZero_64(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
- goto success;
- }
-
- /* q = b / a; b = b % a; */
- if (blen < alen || (blen == alen && lbnCmp_64(b, a, alen) < 0))
- assert(0);
- cy = lbnDiv_64(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
- *(BIGLITTLE(b-blen-1,b+blen)) = cy;
- plen = lbnNorm_64(BIGLITTLE(b-alen,b+alen), blen-alen+1);
- assert(plen);
- blen = lbnNorm_64(b, alen);
- if (!blen)
- goto failure; /* GCD not 1 */
-
- /* t1 += q * t0; */
- assert(plen+t0len <= mlen+1);
- lbnMul_64(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
- plen = lbnNorm_64(p, plen + t0len);
- assert(plen <= mlen);
- if (plen > t1len) {
- lbnZero_64(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
- t1len = plen;
- }
- cy = lbnAddN_64(t1, p, plen);
- if (cy) {
- if (t1len > plen) {
- cy = lbnAdd1_64(BIGLITTLE(t1-plen,t0+plen),
- t1len-plen, cy);
- }
- if (cy) {
- BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
- t1len++;
- }
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
-
- if (!blen)
- goto failure; /* gcd(a, mod) != 1 -- FAIL */
-
- /* return mod-t1 */
- lbnCopy_64(a, mod, mlen);
- assert(t1len <= mlen);
- cy = lbnSubN_64(a, t1, t1len);
- if (cy) {
- assert(mlen > t1len);
- cy = lbnSub1_64(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
- assert(!cy);
- }
-
-success:
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return 0;
-
-failure: /* GCD is not 1 - no inverse exists! */
- y = 1;
-#if BNYIELD
-yield:
-#endif
- LBNFREE(t1, mlen);
- LBNFREE(t0, mlen);
- LBNFREE(p, mlen+1);
- LBNFREE(b, mlen+1);
-
- return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod". Compute them every "bits"
- * for "n" steps. This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- *
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_64(BNWORD64 **array, unsigned n, unsigned bits,
- BNWORD64 const *g, unsigned glen, BNWORD64 *mod, unsigned mlen)
-{
- BNWORD64 *a, *b; /* Temporary double-width accumulators */
- BNWORD64 *a1; /* Pointer to high half of a*/
- BNWORD64 inv; /* Montgomery inverse of LSW of mod */
- BNWORD64 *t;
- unsigned i;
-
- glen = lbnNorm_64(g, glen);
- assert(glen);
-
- assert (mlen == lbnNorm_64(mod, mlen));
- assert (glen <= mlen);
-
- /* Allocate two temporary buffers, and the array slots */
- LBNALLOC(a, BNWORD64, mlen*2);
- if (!a)
- return -1;
- LBNALLOC(b, BNWORD64, mlen*2);
- if (!b) {
- LBNFREE(a, 2*mlen);
- return -1;
- }
-
- /* Okay, all ready */
-
- /* Convert n to Montgomery form */
- inv = BIGLITTLE(mod[-1],mod[0]); /* LSW of modulus */
- assert(inv & 1); /* Modulus must be odd */
- inv = lbnMontInv1_64(inv);
- /* Move g up "mlen" words into a (clearing the low mlen words) */
- a1 = BIGLITTLE(a-mlen,a+mlen);
- lbnCopy_64(a1, g, glen);
- lbnZero_64(a, mlen);
-
- /* Do the division - dump the quotient into the high-order words */
- (void)lbnDiv_64(a1, a, mlen+glen, mod, mlen);
-
- /* Copy the first value into the array */
- t = *array;
- lbnCopy_64(t, a, mlen);
- a1 = a; /* This first value is *not* shifted up */
-
- /* Now compute the remaining n-1 array entries */
- assert(bits);
- assert(n);
- while (--n) {
- i = bits;
- do {
- /* Square a1 into b1 */
- lbnMontSquare_64(b, a1, mod, mlen, inv);
- t = b; b = a; a = t;
- a1 = BIGLITTLE(a-mlen, a+mlen);
- } while (--i);
- t = *++array;
- lbnCopy_64(t, a1, mlen);
- }
-
- /* Hooray, we're done. */
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
- return 0;
-}
-
-/*
- * result = base^exp (mod mod). "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart. (I.e. array[i]
- * is base^(2^(i*bits))).
- *
- * The algorithm consists of:
- * a = b = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_64(BNWORD64 *result, BNWORD64 const * const *array,
- unsigned bits, BNWORD64 const *exp, unsigned elen,
- BNWORD64 const *mod, unsigned mlen)
-{
- BNWORD64 *a, *b, *c, *t;
- BNWORD64 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD64 const *eptr; /* Pointer into exp */
- BNWORD64 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD64 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
-
- mlen = lbnNorm_64(mod, mlen);
- assert (mlen);
-
- elen = lbnNorm_64(exp, elen);
- if (!elen) {
- lbnZero_64(result, mlen);
- BIGLITTLE(result[-1],result[0]) = 1;
- return 0;
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD64, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD64, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD64, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Set up bit buffer for walking the exponent */
- eptr = exp;
- buf = BIGLITTLE(*--eptr, *eptr++);
- ewords = elen-1;
- bufbits = 64;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 64;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD64 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_64(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_64(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_64(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_64(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_64(a, a1, mlen);
- lbnZero_64(a1, mlen);
- lbnMontReduce_64(a, mod, mlen, inv);
- lbnCopy_64(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod). "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart. (I.e. array1[i] is base1^(2^(i*bits))).
- *
- * Bits must be the same in both. (It could be made adjustable, but it's
- * a bit of a pain. Just make them both equal to the larger one.)
- *
- * The algorithm consists of:
- * a = b = (powers of base1 and base2 to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- *
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_64(BNWORD64 *result, unsigned bits,
- BNWORD64 const * const *array1, BNWORD64 const *exp1, unsigned elen1,
- BNWORD64 const * const *array2, BNWORD64 const *exp2,
- unsigned elen2, BNWORD64 const *mod, unsigned mlen)
-{
- BNWORD64 *a, *b, *c, *t;
- BNWORD64 *a1, *b1;
- int anull, bnull; /* Null flags: values are implicitly 1 */
- unsigned i, j, k; /* Loop counters */
- unsigned mask; /* Exponent bits to examime */
- BNWORD64 const *eptr; /* Pointer into exp */
- BNWORD64 buf, curbits, nextword; /* Bit-buffer varaibles */
- BNWORD64 inv; /* Inverse of LSW of modulus */
- unsigned ewords; /* Words of exponent left */
- int bufbits; /* Number of valid bits */
- int y = 0;
- BNWORD64 const * const *array;
-
- mlen = lbnNorm_64(mod, mlen);
- assert (mlen);
-
- elen1 = lbnNorm_64(exp1, elen1);
- if (!elen1) {
- return lbnBasePrecompExp_64(result, array2, bits, exp2, elen2,
- mod, mlen);
- }
- elen2 = lbnNorm_64(exp2, elen2);
- if (!elen2) {
- return lbnBasePrecompExp_64(result, array1, bits, exp1, elen1,
- mod, mlen);
- }
- /*
- * This could be precomputed, but it's so cheap, and it would require
- * making the precomputation structure word-size dependent.
- */
- inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]); /* LSW of modulus */
-
- assert(elen1);
- assert(elen2);
-
- /*
- * Allocate three temporary buffers. The current numbers generally
- * live in the upper halves of these buffers.
- */
- LBNALLOC(a, BNWORD64, mlen*2);
- if (a) {
- LBNALLOC(b, BNWORD64, mlen*2);
- if (b) {
- LBNALLOC(c, BNWORD64, mlen*2);
- if (c)
- goto allocated;
- LBNFREE(b, 2*mlen);
- }
- LBNFREE(a, 2*mlen);
- }
- return -1;
-
-allocated:
-
- anull = bnull = 1;
-
- mask = (1u<<bits) - 1;
- for (i = mask; i; --i) {
- /* Walk each exponent in turn */
- for (k = 0; k < 2; k++) {
- /* Set up the exponent for walking */
- array = k ? array2 : array1;
- eptr = k ? exp2 : exp1;
- ewords = (k ? elen2 : elen1) - 1;
- /* Set up bit buffer for walking the exponent */
- buf = BIGLITTLE(*--eptr, *eptr++);
- bufbits = 64;
- for (j = 0; ewords || buf; j++) {
- /* Shift down current buffer */
- curbits = buf;
- buf >>= bits;
- /* If necessary, add next word */
- bufbits -= bits;
- if (bufbits < 0 && ewords > 0) {
- nextword = BIGLITTLE(*--eptr, *eptr++);
- ewords--;
- curbits |= nextword << (bufbits+bits);
- buf = nextword >> -bufbits;
- bufbits += 64;
- }
- /* If appropriate, multiply b *= array[j] */
- if ((curbits & mask) == i) {
- BNWORD64 const *d = array[j];
-
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (bnull) {
- lbnCopy_64(b1, d, mlen);
- bnull = 0;
- } else {
- lbnMontMul_64(c, b1, d, mod, mlen, inv);
- t = c; c = b; b = t;
- }
-#if BNYIELD
- if (bnYield && (y = bnYield() < 0))
- goto yield;
-#endif
- }
- }
- }
-
- /* Multiply a *= b */
- if (!bnull) {
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- b1 = BIGLITTLE(b-mlen-1,b+mlen);
- if (anull) {
- lbnCopy_64(a1, b1, mlen);
- anull = 0;
- } else {
- lbnMontMul_64(c, a1, b1, mod, mlen, inv);
- t = c; c = a; a = t;
- }
- }
- }
-
- assert(!anull); /* If it were, elen would have been 0 */
-
- /* Convert out of Montgomery form and return */
- a1 = BIGLITTLE(a-mlen-1,a+mlen);
- lbnCopy_64(a, a1, mlen);
- lbnZero_64(a1, mlen);
- lbnMontReduce_64(a, mod, mlen, inv);
- lbnCopy_64(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
- LBNFREE(c, 2*mlen);
- LBNFREE(b, 2*mlen);
- LBNFREE(a, 2*mlen);
-
- return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn64.h b/jni/libzrtp/sources/bnlib/lbn64.h
deleted file mode 100644
index 283e248..0000000
--- a/jni/libzrtp/sources/bnlib/lbn64.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN64_H
-#define LBN64_H
-
-#include "lbn.h"
-
-#ifndef BNWORD64
-#error 64-bit bignum library requires a 64-bit data type
-#endif
-
-#ifndef lbnCopy_64
-void lbnCopy_64(BNWORD64 *dest, BNWORD64 const *src, unsigned len);
-#endif
-#ifndef lbnZero_64
-void lbnZero_64(BNWORD64 *num, unsigned len);
-#endif
-#ifndef lbnNeg_64
-void lbnNeg_64(BNWORD64 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_64
-BNWORD64 lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry);
-#endif
-#ifndef lbnSub1_64
-BNWORD64 lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow);
-#endif
-
-#ifndef lbnAddN_64
-BNWORD64 lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_64
-BNWORD64 lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_64
-int lbnCmp_64(BNWORD64 const *num1, BNWORD64 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_64
-void lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-#ifndef lbnMulAdd1_64
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-#ifndef lbnMulSub1_64
-BNWORD64 lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-
-#ifndef lbnLshift_64
-BNWORD64 lbnLshift_64(BNWORD64 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_64
-BNWORD64 lbnDouble_64(BNWORD64 *num, unsigned len);
-#endif
-#ifndef lbnRshift_64
-BNWORD64 lbnRshift_64(BNWORD64 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_64
-void lbnMul_64(BNWORD64 *prod, BNWORD64 const *num1, unsigned len1,
- BNWORD64 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_64
-void lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_64
-unsigned lbnNorm_64(BNWORD64 const *num, unsigned len);
-#endif
-#ifndef lbnBits_64
-unsigned lbnBits_64(BNWORD64 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_64
-void lbnExtractBigBytes_64(BNWORD64 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_64
-void lbnInsertBigBytes_64(BNWORD64 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_64
-void lbnExtractLittleBytes_64(BNWORD64 const *bn, unsigned char *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_64
-void lbnInsertLittleBytes_64(BNWORD64 *n, unsigned char const *buf,
- unsigned lsbyte, unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_64
-BNWORD64 lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d);
-#endif
-#ifndef lbnDiv1_64
-BNWORD64 lbnDiv1_64(BNWORD64 *q, BNWORD64 *rem,
- BNWORD64 const *n, unsigned len, BNWORD64 d);
-#endif
-#ifndef lbnModQ_64
-unsigned lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_64
-BNWORD64
-lbnDiv_64(BNWORD64 *q, BNWORD64 *n, unsigned nlen, BNWORD64 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_64
-BNWORD64 lbnMontInv1_64(BNWORD64 const x);
-#endif
-#ifndef lbnMontReduce_64
-void lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned const mlen,
- BNWORD64 inv);
-#endif
-#ifndef lbnToMont_64
-void lbnToMont_64(BNWORD64 *n, unsigned nlen, BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_64
-void lbnFromMont_64(BNWORD64 *n, BNWORD64 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_64
-int lbnExpMod_64(BNWORD64 *result, BNWORD64 const *n, unsigned nlen,
- BNWORD64 const *exp, unsigned elen, BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_64
-int lbnDoubleExpMod_64(BNWORD64 *result,
- BNWORD64 const *n1, unsigned n1len, BNWORD64 const *e1, unsigned e1len,
- BNWORD64 const *n2, unsigned n2len, BNWORD64 const *e2, unsigned e2len,
- BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_64
-int lbnTwoExpMod_64(BNWORD64 *n, BNWORD64 const *exp, unsigned elen,
- BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_64
-int lbnGcd_64(BNWORD64 *a, unsigned alen, BNWORD64 *b, unsigned blen,
- unsigned *rlen);
-#endif
-#ifndef lbnInv_64
-int lbnInv_64(BNWORD64 *a, unsigned alen, BNWORD64 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_64(BNWORD64 **array, unsigned n, unsigned bits,
- BNWORD64 const *g, unsigned glen, BNWORD64 *mod, unsigned mlen);
-int lbnBasePrecompExp_64(BNWORD64 *result, BNWORD64 const * const *array,
- unsigned bits, BNWORD64 const *exp, unsigned elen,
- BNWORD64 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_64(BNWORD64 *result, unsigned bits,
- BNWORD64 const * const *array1, BNWORD64 const *exp1, unsigned elen1,
- BNWORD64 const * const *array2, BNWORD64 const *exp2,
- unsigned elen2, BNWORD64 const *mod, unsigned mlen);
-
-#endif /* LBN64_H */
diff --git a/jni/libzrtp/sources/bnlib/lbnmem.c b/jni/libzrtp/sources/bnlib/lbnmem.c
deleted file mode 100644
index 56d2002..0000000
--- a/jni/libzrtp/sources/bnlib/lbnmem.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * lbnmem.c - low-level bignum memory handling.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * Note that in all cases, the pointers passed around
- * are pointers to the *least* significant end of the word.
- * On big-endian machines, these are pointers to the *end*
- * of the allocated range.
- *
- * BNSECURE is a simple level of security; for more security
- * change these function to use locked unswappable memory.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_STDLIB_H
-#define NO_STDLIB_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_STDLIB_H
-#include <stdlib.h> /* For malloc() & co. */
-#else
-void *malloc();
-void *realloc();
-void free();
-#endif
-
-#if !NO_STRING_H
-#include <string.h> /* For memset */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-/* Development debugging */
-#include "../dbmalloc/malloc.h"
-#endif
-
-#include "lbn.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef lbnMemWipe
-void
-lbnMemWipe(void *ptr, unsigned bytes)
-{
- memset(ptr, 0, bytes);
-}
-#define lbnMemWipe(ptr, bytes) memset(ptr, 0, bytes)
-#endif
-
-#ifndef lbnMemAlloc
-void *
-lbnMemAlloc(unsigned bytes)
-{
- return malloc(bytes);
-}
-#define lbnMemAlloc(bytes) malloc(bytes)
-#endif
-
-#ifndef lbnMemFree
-void
-lbnMemFree(void *ptr, unsigned bytes)
-{
- lbnMemWipe(ptr, bytes);
- free(ptr);
-}
-#endif
-
-#ifndef lbnRealloc
-#if defined(lbnMemRealloc) || !BNSECURE
-void *
-lbnRealloc(void *ptr, unsigned oldbytes, unsigned newbytes)
-{
- if (ptr) {
- BIG(ptr = (char *)ptr - oldbytes;)
- if (newbytes < oldbytes)
- memmove(ptr, (char *)ptr + oldbytes-newbytes, oldbytes);
- }
-#ifdef lbnMemRealloc
- ptr = lbnMemRealloc(ptr, oldbytes, newbytes);
-#else
- ptr = realloc(ptr, newbytes);
-#endif
- if (ptr) {
- if (newbytes > oldbytes)
- memmove((char *)ptr + newbytes-oldbytes, ptr, oldbytes);
- BIG(ptr = (char *)ptr + newbytes;)
- }
-
- return ptr;
-}
-
-#else /* BNSECURE */
-
-void *
-lbnRealloc(void *oldptr, unsigned oldbytes, unsigned newbytes)
-{
- void *newptr = lbnMemAlloc(newbytes);
-
- if (!newptr)
- return newptr;
- if (!oldptr)
- return BIGLITTLE((char *)newptr+newbytes, newptr);
-
- /*
- * The following copies are a bit non-obvious in the big-endian case
- * because one of the pointers points to the *end* of allocated memory.
- */
- if (newbytes > oldbytes) { /* Copy all of old into part of new */
- BIG(newptr = (char *)newptr + newbytes;)
- BIG(oldptr = (char *)oldptr - oldbytes;)
- memcpy(BIGLITTLE((char *)newptr-oldbytes, newptr), oldptr,
- oldbytes);
- } else { /* Copy part of old into all of new */
- memcpy(newptr, BIGLITTLE((char *)oldptr-newbytes, oldptr),
- newbytes);
- BIG(newptr = (char *)newptr + newbytes;)
- BIG(oldptr = (char *)oldptr - oldbytes;)
- }
-
- lbnMemFree(oldptr, oldbytes);
-
- return newptr;
-}
-#endif /* BNSECURE */
-#endif /* !lbnRealloc */
diff --git a/jni/libzrtp/sources/bnlib/lbnmem.h b/jni/libzrtp/sources/bnlib/lbnmem.h
deleted file mode 100644
index f77298b..0000000
--- a/jni/libzrtp/sources/bnlib/lbnmem.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Operations on the usual buffers of bytes
- */
-#ifndef BNSECURE
-#define BNSECURE 1
-#endif
-
-/*
- * These operations act on buffers of memory, just like malloc & free.
- * One exception: it is not legal to pass a NULL pointer to lbnMemFree.
- */
-
-#ifndef lbnMemAlloc
-void *lbnMemAlloc(unsigned bytes);
-#endif
-
-#ifndef lbnMemFree
-void lbnMemFree(void *ptr, unsigned bytes);
-#endif
-
-/* This wipes out a buffer of bytes if necessary needed. */
-
-#ifndef lbnMemWipe
-#if BNSECURE
-void lbnMemWipe(void *ptr, unsigned bytes);
-#else
-#define lbnMemWipe(ptr, bytes) (void)(ptr,bytes)
-#endif
-#endif /* !lbnMemWipe */
-
-/*
- * lbnRealloc is NOT like realloc(); it's endian-sensitive!
- * If lbnMemRealloc is #defined, lbnRealloc will be defined in terms of it.
- * It is legal to pass a NULL pointer to lbnRealloc, although oldbytes
- * will always be sero.
- */
-#ifndef lbnRealloc
-void *lbnRealloc(void *ptr, unsigned oldbytes, unsigned newbytes);
-#endif
-
-
-/*
- * These macros are the ones actually used most often in the math library.
- * They take and return pointers to the *end* of the given buffer, and
- * take sizes in terms of words, not bytes.
- *
- * Note that LBNALLOC takes the pointer as an argument instead of returning
- * the value.
- *
- * Note also that these macros are only useable if you have included
- * lbn.h (for the BIG and BIGLITTLE macros), which this file does NOT include.
- */
-
-#define LBNALLOC(p,type,words) BIGLITTLE( \
- if ( ((p) = (type *)lbnMemAlloc((words)*sizeof*(p))) != 0) \
- (p) += (words), \
- (p) = (type *)lbnMemAlloc((words) * sizeof*(p)) \
- )
-#define LBNFREE(p,words) lbnMemFree((p) BIG(-(words)), (words) * sizeof*(p))
-#define LBNREALLOC(p,old,new) \
- lbnRealloc(p, (old) * sizeof*(p), (new) * sizeof*(p))
-#define LBNWIPE(p,words) lbnMemWipe((p) BIG(-(words)), (words) * sizeof*(p))
-
diff --git a/jni/libzrtp/sources/bnlib/legal.c b/jni/libzrtp/sources/bnlib/legal.c
deleted file mode 100644
index 343db14..0000000
--- a/jni/libzrtp/sources/bnlib/legal.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * bnlib - BigNum multiprecision integer math library.
- * Copyright (c) 1995, 2005 Colin Plumb. All rights reserved.
- * For licensing information, please contact
- * Philip R. Zimmermann <prz@mit.edu>, http://philzimmermann.com
- *
- * This subroutine library is licensed to the general public under
- * the GNU GPL, version 2. Any software that uses code under a GPL
- * license is itself subject to the same GPL licensing terms.
- *
- * For licensing bnlib under alternate terms, so that you can use it without
- * your own product becoming infected with the obligations of the GPL,
- * you should contact Philip Zimmermann, who has unlimited sublicensing
- * rights under non-GPL terms.
- *
- * This module must be packaged together with the rest of the bnlib
- * source code. That's why it's in a .c file.
- *
- * Lawyers have requested that the following information be included:
- *
- * Warranties:
- * This software is provided "as is," with no warranty expressed
- * or implied.
- *
- * Export controls:
- * This software may be subject to export controls by the US Commerce
- * Department's Bureau of Industry and Security.
- *
- */
-
-/* Force inclusion of this copyright string. It may be commented out only
- * if necessary in order to squeeze bnlib into memory-starved environments. */
-#include "legal.h"
-volatile const char bnCopyright[] =
- "\0bnlib Copyright (c) 1995, 2005 Colin Plumb.";
-
-
-/****************************************************************************
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
-
-****************************************************************************/
diff --git a/jni/libzrtp/sources/bnlib/legal.h b/jni/libzrtp/sources/bnlib/legal.h
deleted file mode 100644
index e28cd91..0000000
--- a/jni/libzrtp/sources/bnlib/legal.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * We want the copyright string to be accessable to the unix strings command
- * in the final linked binary, and we don't want the linker to remove it if
- * it's not referenced, so we do that by using the volatile qualifier.
- *
- * ANSI C standard, section 3.5.3: "An object that has volatile-qualified
- * type may be modified in ways unknown to the implementation or have
- * other unknown side effects." Yes, we can't expect a compiler to
- * understand law...
- */
-extern volatile const char bnCopyright[];
diff --git a/jni/libzrtp/sources/bnlib/prime.c b/jni/libzrtp/sources/bnlib/prime.c
deleted file mode 100644
index adf17d6..0000000
--- a/jni/libzrtp/sources/bnlib/prime.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Prime generation using the bignum library and sieving.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#include <stdarg.h> /* We just can't live without this... */
-
-#ifndef BNDEBUG
-#define BNDEBUG 1
-#endif
-#if BNDEBUG
-#include <stdio.h>
-#endif
-
-#include "bn.h"
-#include "lbnmem.h"
-#include "prime.h"
-#include "sieve.h"
-
-#include "kludge.h"
-
-/* Size of the shuffle table */
-#define SHUFFLE 256
-/* Size of the sieve area */
-#define SIEVE 32768u/16
-
-/* Confirmation tests. The first one *must* be 2 */
-static unsigned const confirm[] = {2, 3, 5, 7, 11, 13, 17};
-#define CONFIRMTESTS (sizeof(confirm)/sizeof(*confirm))
-
-/*
- * Helper function that does the slow primality test.
- * bn is the input bignum; a and e are temporary buffers that are
- * allocated by the caller to save overhead.
- *
- * Returns 0 if prime, >0 if not prime, and -1 on error (out of memory).
- * If not prime, returns the number of modular exponentiations performed.
- * Calls the given progress function with a '*' for each primality test
- * that is passed.
- *
- * The testing consists of strong pseudoprimality tests, to the bases given
- * in the confirm[] array above. (Also called Miller-Rabin, although that's
- * not technically correct if we're using fixed bases.) Some people worry
- * that this might not be enough. Number theorists may wish to generate
- * primality proofs, but for random inputs, this returns non-primes with
- * a probability which is quite negligible, which is good enough.
- *
- * It has been proved (see Carl Pomerance, "On the Distribution of
- * Pseudoprimes", Math. Comp. v.37 (1981) pp. 587-593) that the number of
- * pseudoprimes (composite numbers that pass a Fermat test to the base 2)
- * less than x is bounded by:
- * exp(ln(x)^(5/14)) <= P_2(x) ### CHECK THIS FORMULA - it looks wrong! ###
- * P_2(x) <= x * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))).
- * Thus, the local density of Pseudoprimes near x is at most
- * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))), and at least
- * exp(ln(x)^(5/14) - ln(x)). Here are some values of this function
- * for various k-bit numbers x = 2^k:
- * Bits Density <= Bit equivalent Density >= Bit equivalent
- * 128 3.577869e-07 21.414396 4.202213e-37 120.840190
- * 192 4.175629e-10 31.157288 4.936250e-56 183.724558
- * 256 5.804314e-13 40.647940 4.977813e-75 246.829095
- * 384 1.578039e-18 59.136573 3.938861e-113 373.400096
- * 512 5.858255e-24 77.175803 2.563353e-151 500.253110
- * 768 1.489276e-34 112.370944 7.872825e-228 754.422724
- * 1024 6.633188e-45 146.757062 1.882404e-304 1008.953565
- *
- * As you can see, there's quite a bit of slop between these estimates.
- * In fact, the density of pseudoprimes is conjectured to be closer to the
- * square of that upper bound. E.g. the density of pseudoprimes of size
- * 256 is around 3 * 10^-27. The density of primes is very high, from
- * 0.005636 at 256 bits to 0.001409 at 1024 bits, i.e. more than 10^-3.
- *
- * For those people used to cryptographic levels of security where the
- * 56 bits of DES key space is too small because it's exhaustible with
- * custom hardware searching engines, note that you are not generating
- * 50,000,000 primes per second on each of 56,000 custom hardware chips
- * for several hours. The chances that another Dinosaur Killer asteroid
- * will land today is about 10^-11 or 2^-36, so it would be better to
- * spend your time worrying about *that*. Well, okay, there should be
- * some derating for the chance that astronomers haven't seen it yet,
- * but I think you get the idea. For a good feel about the probability
- * of various events, I have heard that a good book is by E'mile Borel,
- * "Les Probabilite's et la vie". (The 's are accents, not apostrophes.)
- *
- * For more on the subject, try "Finding Four Million Large Random Primes",
- * by Ronald Rivest, in Advancess in Cryptology: Proceedings of Crypto
- * '90. He used a small-divisor test, then a Fermat test to the base 2,
- * and then 8 iterations of a Miller-Rabin test. About 718 million random
- * 256-bit integers were generated, 43,741,404 passed the small divisor
- * test, 4,058,000 passed the Fermat test, and all 4,058,000 passed all
- * 8 iterations of the Miller-Rabin test, proving their primality beyond
- * most reasonable doubts.
- *
- * If the probability of getting a pseudoprime is some small p, then the
- * probability of not getting it in t trials is (1-p)^t. Remember that,
- * for small p, (1-p)^(1/p) ~ 1/e, the base of natural logarithms.
- * (This is more commonly expressed as e = lim_{x\to\infty} (1+1/x)^x.)
- * Thus, (1-p)^t ~ e^(-p*t) = exp(-p*t). So the odds of being able to
- * do this many tests without seeing a pseudoprime if you assume that
- * p = 10^-6 (one in a million) is one in 57.86. If you assume that
- * p = 2*10^-6, it's one in 3347.6. So it's implausible that the density
- * of pseudoprimes is much more than one millionth the density of primes.
- *
- * He also gives a theoretical argument that the chance of finding a
- * 256-bit non-prime which satisfies one Fermat test to the base 2 is
- * less than 10^-22. The small divisor test improves this number, and
- * if the numbers are 512 bits (as needed for a 1024-bit key) the odds
- * of failure shrink to about 10^-44. Thus, he concludes, for practical
- * purposes *one* Fermat test to the base 2 is sufficient.
- */
-static int
-primeTest(struct BigNum const *bn, struct BigNum *e, struct BigNum *a,
- int (*f)(void *arg, int c), void *arg)
-{
- unsigned i, j;
- unsigned k, l;
- int err;
-
-#if BNDEBUG /* Debugging */
- /*
- * This is debugging code to test the sieving stage.
- * If the sieving is wrong, it will let past numbers with
- * small divisors. The prime test here will still work, and
- * weed them out, but you'll be doing a lot more slow tests,
- * and presumably excluding from consideration some other numbers
- * which might be prime. This check just verifies that none
- * of the candidates have any small divisors. If this
- * code is enabled and never triggers, you can feel quite
- * confident that the sieving is doing its job.
- */
- i = bnLSWord(bn);
- if (!(i % 2)) printf("bn div by 2!");
- i = bnModQ(bn, 51051); /* 51051 = 3 * 7 * 11 * 13 * 17 */
- if (!(i % 3)) printf("bn div by 3!");
- if (!(i % 7)) printf("bn div by 7!");
- if (!(i % 11)) printf("bn div by 11!");
- if (!(i % 13)) printf("bn div by 13!");
- if (!(i % 17)) printf("bn div by 17!");
- i = bnModQ(bn, 63365); /* 63365 = 5 * 19 * 23 * 29 */
- if (!(i % 5)) printf("bn div by 5!");
- if (!(i % 19)) printf("bn div by 19!");
- if (!(i % 23)) printf("bn div by 23!");
- if (!(i % 29)) printf("bn div by 29!");
- i = bnModQ(bn, 47027); /* 47027 = 31 * 37 * 41 */
- if (!(i % 31)) printf("bn div by 31!");
- if (!(i % 37)) printf("bn div by 37!");
- if (!(i % 41)) printf("bn div by 41!");
-#endif
-
- /*
- * Now, check that bn is prime. If it passes to the base 2,
- * it's prime beyond all reasonable doubt, and everything else
- * is just gravy, but it gives people warm fuzzies to do it.
- *
- * This starts with verifying Euler's criterion for a base of 2.
- * This is the fastest pseudoprimality test that I know of,
- * saving a modular squaring over a Fermat test, as well as
- * being stronger. 7/8 of the time, it's as strong as a strong
- * pseudoprimality test, too. (The exception being when bn ==
- * 1 mod 8 and 2 is a quartic residue, i.e. bn is of the form
- * a^2 + (8*b)^2.) The precise series of tricks used here is
- * not documented anywhere, so here's an explanation.
- * Euler's criterion states that if p is prime then a^((p-1)/2)
- * is congruent to Jacobi(a,p), modulo p. Jacobi(a,p) is
- * a function which is +1 if a is a square modulo p, and -1 if
- * it is not. For a = 2, this is particularly simple. It's
- * +1 if p == +/-1 (mod 8), and -1 if m == +/-3 (mod 8).
- * If p == 3 mod 4, then all a strong test does is compute
- * 2^((p-1)/2). and see if it's +1 or -1. (Euler's criterion
- * says *which* it should be.) If p == 5 (mod 8), then
- * 2^((p-1)/2) is -1, so the initial step in a strong test,
- * looking at 2^((p-1)/4), is wasted - you're not going to
- * find a +/-1 before then if it *is* prime, and it shouldn't
- * have either of those values if it isn't. So don't bother.
- *
- * The remaining case is p == 1 (mod 8). In this case, we
- * expect 2^((p-1)/2) == 1 (mod p), so we expect that the
- * square root of this, 2^((p-1)/4), will be +/-1 (mod p).
- * Evaluating this saves us a modular squaring 1/4 of the time.
- * If it's -1, a strong pseudoprimality test would call p
- * prime as well. Only if the result is +1, indicating that
- * 2 is not only a quadratic residue, but a quartic one as well,
- * does a strong pseudoprimality test verify more things than
- * this test does. Good enough.
- *
- * We could back that down another step, looking at 2^((p-1)/8)
- * if there was a cheap way to determine if 2 were expected to
- * be a quartic residue or not. Dirichlet proved that 2 is
- * a quartic residue iff p is of the form a^2 + (8*b^2).
- * All primes == 1 (mod 4) can be expressed as a^2 + (2*b)^2,
- * but I see no cheap way to evaluate this condition.
- */
- if (bnCopy(e, bn) < 0)
- return -1;
- (void)bnSubQ(e, 1);
- l = bnLSWord(e);
-
- j = 1; /* Where to start in prime array for strong prime tests */
-
- if (l & 7) {
- bnRShift(e, 1);
- if (bnTwoExpMod(a, e, bn) < 0)
- return -1;
- if ((l & 7) == 6) {
- /* bn == 7 mod 8, expect +1 */
- if (bnBits(a) != 1)
- return 1; /* Not prime */
- k = 1;
- } else {
- /* bn == 3 or 5 mod 8, expect -1 == bn-1 */
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) != 0)
- return 1; /* Not prime */
- k = 1;
- if (l & 4) {
- /* bn == 5 mod 8, make odd for strong tests */
- bnRShift(e, 1);
- k = 2;
- }
- }
- } else {
- /* bn == 1 mod 8, expect 2^((bn-1)/4) == +/-1 mod bn */
- bnRShift(e, 2);
- if (bnTwoExpMod(a, e, bn) < 0)
- return -1;
- if (bnBits(a) == 1) {
- j = 0; /* Re-do strong prime test to base 2 */
- } else {
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) != 0)
- return 1; /* Not prime */
- }
- k = 2 + bnMakeOdd(e);
- }
- /* It's prime! Now go on to confirmation tests */
-
- /*
- * Now, e = (bn-1)/2^k is odd. k >= 1, and has a given value
- * with probability 2^-k, so its expected value is 2.
- * j = 1 in the usual case when the previous test was as good as
- * a strong prime test, but 1/8 of the time, j = 0 because
- * the strong prime test to the base 2 needs to be re-done.
- */
- for (i = j; i < CONFIRMTESTS; i++) {
- if (f && (err = f(arg, '*')) < 0)
- return err;
- (void)bnSetQ(a, confirm[i]);
- if (bnExpMod(a, a, e, bn) < 0)
- return -1;
- if (bnBits(a) == 1)
- continue; /* Passed this test */
-
- l = k;
- for (;;) {
- if (bnAddQ(a, 1) < 0)
- return -1;
- if (bnCmp(a, bn) == 0) /* Was result bn-1? */
- break; /* Prime */
- if (!--l) /* Reached end, not -1? luck? */
- return i+2-j; /* Failed, not prime */
- /* This portion is executed, on average, once. */
- (void)bnSubQ(a, 1); /* Put a back where it was. */
- if (bnSquare(a, a) < 0 || bnMod(a, a, bn) < 0)
- return -1;
- if (bnBits(a) == 1)
- return i+2-j; /* Failed, not prime */
- }
- /* It worked (to the base confirm[i]) */
- }
-
- /* Yes, we've decided that it's prime. */
- if (f && (err = f(arg, '*')) < 0)
- return err;
- return 0; /* Prime! */
-}
-
-/*
- * Add x*y to bn, which is usually (but not always) < 65536.
- * Do it in a simple linear manner.
- */
-static int
-bnAddMult(struct BigNum *bn, unsigned x, unsigned y)
-{
- unsigned long z = (unsigned long)x * y;
-
- while (z > 65535) {
- if (bnAddQ(bn, 65535) < 0)
- return -1;
- z -= 65535;
- }
- return bnAddQ(bn, (unsigned)z);
-}
-
-static int
-bnSubMult(struct BigNum *bn, unsigned x, unsigned y)
-{
- unsigned long z = (unsigned long)x * y;
-
- while (z > 65535) {
- if (bnSubQ(bn, 65535) < 0)
- return -1;
- z -= 65535;
- }
- return bnSubQ(bn, (unsigned)z);
-}
-
-/*
- * Modifies the bignum to return a nearby (slightly larger) number which
- * is a probable prime. Returns >=0 on success or -1 on failure (out of
- * memory). The return value is the number of unsuccessful modular
- * exponentiations performed. This never gives up searching.
- *
- * All other arguments are optional. They may be NULL. They are:
- *
- * unsigned (*rand)(unsigned limit)
- * For better distributed numbers, supply a non-null pointer to a
- * function which returns a random x, 0 <= x < limit. (It may make it
- * simpler to know that 0 < limit <= SHUFFLE, so you need at most a byte.)
- * The program generates a large window of sieve data and then does
- * pseudoprimality tests on the data. If a rand function is supplied,
- * the candidates which survive sieving are shuffled with a window of
- * size SHUFFLE before testing to increase the uniformity of the prime
- * selection. This isn't perfect, but it reduces the correlation between
- * the size of the prime-free gap before a prime and the probability
- * that that prime will be found by a sequential search.
- *
- * If rand is NULL, sequential search is used. If you want sequential
- * search, note that the search begins with the given number; if you're
- * trying to generate consecutive primes, you must increment the previous
- * one by two before calling this again.
- *
- * int (*f)(void *arg, int c), void *arg
- * The function f argument, if non-NULL, is called with progress indicator
- * characters for printing. A dot (.) is written every time a primality test
- * is failed, a star (*) every time one is passed, and a slash (/) in the
- * (very rare) case that the sieve was emptied without finding a prime
- * and is being refilled. f is also passed the void *arg argument for
- * private context storage. If f returns < 0, the test aborts and returns
- * that value immediately. (bn is set to the last value tested, so you
- * can increment bn and continue.)
- *
- * The "exponent" argument, and following unsigned numbers, are exponents
- * for which an inverse is desired, modulo p. For a d to exist such that
- * (x^e)^d == x (mod p), then d*e == 1 (mod p-1), so gcd(e,p-1) must be 1.
- * The prime returned is constrained to not be congruent to 1 modulo
- * any of the zero-terminated list of 16-bit numbers. Note that this list
- * should contain all the small prime factors of e. (You'll have to test
- * for large prime factors of e elsewhere, but the chances of needing to
- * generate another prime are low.)
- *
- * The list is terminated by a 0, and may be empty.
- */
-int
-primeGen(struct BigNum *bn, unsigned (*rand)(unsigned),
- int (*f)(void *arg, int c), void *arg, unsigned exponent, ...)
-{
- int retval;
- int modexps = 0;
- unsigned short offsets[SHUFFLE];
- unsigned i, j;
- unsigned p, q, prev;
- struct BigNum a, e;
-#ifdef MSDOS
- unsigned char *sieve;
-#else
- unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
- sieve = lbnMemAlloc(SIEVE);
- if (!sieve)
- return -1;
-#endif
-
- bnBegin(&a);
- bnBegin(&e);
-
-#if 0 /* Self-test (not used for production) */
-{
- struct BigNum t;
- static unsigned char const prime1[] = {5};
- static unsigned char const prime2[] = {7};
- static unsigned char const prime3[] = {11};
- static unsigned char const prime4[] = {1, 1}; /* 257 */
- static unsigned char const prime5[] = {0xFF, 0xF1}; /* 65521 */
- static unsigned char const prime6[] = {1, 0, 1}; /* 65537 */
- static unsigned char const prime7[] = {1, 0, 3}; /* 65539 */
- /* A small prime: 1234567891 */
- static unsigned char const prime8[] = {0x49, 0x96, 0x02, 0xD3};
- /* A slightly larger prime: 12345678901234567891 */
- static unsigned char const prime9[] = {
- 0xAB, 0x54, 0xA9, 0x8C, 0xEB, 0x1F, 0x0A, 0xD3 };
- /*
- * No, 123456789012345678901234567891 isn't prime; it's just a
- * lucky, easy-to-remember conicidence. (You have to go to
- * ...4567907 for a prime.)
- */
- static struct {
- unsigned char const *prime;
- unsigned size;
- } const primelist[] = {
- { prime1, sizeof(prime1) },
- { prime2, sizeof(prime2) },
- { prime3, sizeof(prime3) },
- { prime4, sizeof(prime4) },
- { prime5, sizeof(prime5) },
- { prime6, sizeof(prime6) },
- { prime7, sizeof(prime7) },
- { prime8, sizeof(prime8) },
- { prime9, sizeof(prime9) } };
-
- bnBegin(&t);
-
- for (i = 0; i < sizeof(primelist)/sizeof(primelist[0]); i++) {
- bnInsertBytes(&t, primelist[i].prime, 0,
- primelist[i].size);
- bnCopy(&e, &t);
- (void)bnSubQ(&e, 1);
- bnTwoExpMod(&a, &e, &t);
- p = bnBits(&a);
- if (p != 1) {
- printf(
- "Bug: Fermat(2) %u-bit output (1 expected)\n", p);
- fputs("Prime = 0x", stdout);
- for (j = 0; j < primelist[i].size; j++)
- printf("%02X", primelist[i].prime[j]);
- putchar('\n');
- }
- bnSetQ(&a, 3);
- bnExpMod(&a, &a, &e, &t);
- p = bnBits(&a);
- if (p != 1) {
- printf(
- "Bug: Fermat(3) %u-bit output (1 expected)\n", p);
- fputs("Prime = 0x", stdout);
- for (j = 0; j < primelist[i].size; j++)
- printf("%02X", primelist[i].prime[j]);
- putchar('\n');
- }
- }
-
- bnEnd(&t);
-}
-#endif
-
- /* First, make sure that bn is odd. */
- if ((bnLSWord(bn) & 1) == 0)
- (void)bnAddQ(bn, 1);
-
-retry:
- /* Then build a sieve starting at bn. */
- sieveBuild(sieve, SIEVE, bn, 2, 0);
-
- /* Do the extra exponent sieving */
- if (exponent) {
- va_list ap;
- unsigned t = exponent;
-
- va_start(ap, exponent);
-
- do {
- /* The exponent had better be odd! */
- assert(t & 1);
-
- i = bnModQ(bn, t);
- /* Find 1-i */
- if (i == 0)
- i = 1;
- else if (--i)
- i = t - i;
-
- /* Divide by 2, modulo the exponent */
- i = (i & 1) ? i/2 + t/2 + 1 : i/2;
-
- /* Remove all following multiples from the sieve. */
- sieveSingle(sieve, SIEVE, i, t);
-
- /* Get the next exponent value */
- t = va_arg(ap, unsigned);
- } while (t);
-
- va_end(ap);
- }
-
- /* Fill up the offsets array with the first SHUFFLE candidates */
- i = p = 0;
- /* Get first prime */
- if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
- offsets[i++] = p;
- p = sieveSearch(sieve, SIEVE, p);
- }
- /*
- * Okay, from this point onwards, p is always the next entry
- * from the sieve, that has not been added to the shuffle table,
- * and is 0 iff the sieve has been exhausted.
- *
- * If we want to shuffle, then fill the shuffle table until the
- * sieve is exhausted or the table is full.
- */
- if (rand && p) {
- do {
- offsets[i++] = p;
- p = sieveSearch(sieve, SIEVE, p);
- } while (p && i < SHUFFLE);
- }
-
- /* Choose a random candidate for experimentation */
- prev = 0;
- while (i) {
- /* Pick a random entry from the shuffle table */
- j = rand ? rand(i) : 0;
- q = offsets[j]; /* The entry to use */
-
- /* Replace the entry with some more data, if possible */
- if (p) {
- offsets[j] = p;
- p = sieveSearch(sieve, SIEVE, p);
- } else {
- offsets[j] = offsets[--i];
- offsets[i] = 0;
- }
-
- /* Adjust bn to have the right value */
- if ((q > prev ? bnAddMult(bn, q-prev, 2)
- : bnSubMult(bn, prev-q, 2)) < 0)
- goto failed;
- prev = q;
-
- /* Now do the Fermat tests */
- retval = primeTest(bn, &e, &a, f, arg);
- if (retval <= 0)
- goto done; /* Success or error */
- modexps += retval;
- if (f && (retval = f(arg, '.')) < 0)
- goto done;
- }
-
- /* Ran out of sieve space - increase bn and keep trying. */
- if (bnAddMult(bn, SIEVE*8-prev, 2) < 0)
- goto failed;
- if (f && (retval = f(arg, '/')) < 0)
- goto done;
- goto retry;
-
-failed:
- retval = -1;
-done:
- bnEnd(&e);
- bnEnd(&a);
- lbnMemWipe(offsets, sizeof(offsets));
-#ifdef MSDOS
- lbnMemFree(sieve, SIEVE);
-#else
- lbnMemWipe(sieve, sizeof(sieve));
-#endif
-
- return retval < 0 ? retval : modexps + CONFIRMTESTS;
-}
-
-/*
- * Similar, but searches forward from the given starting value in steps of
- * "step" rather than 1. The step size must be even, and bn must be odd.
- * Among other possibilities, this can be used to generate "strong"
- * primes, where p-1 has a large prime factor.
- */
-int
-primeGenStrong(struct BigNum *bn, struct BigNum const *step,
- int (*f)(void *arg, int c), void *arg)
-{
- int retval;
- unsigned p, prev;
- struct BigNum a, e;
- int modexps = 0;
-#ifdef MSDOS
- unsigned char *sieve;
-#else
- unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
- sieve = lbnMemAlloc(SIEVE);
- if (!sieve)
- return -1;
-#endif
-
- /* Step must be even and bn must be odd */
- assert((bnLSWord(step) & 1) == 0);
- assert((bnLSWord(bn) & 1) == 1);
-
- bnBegin(&a);
- bnBegin(&e);
-
- for (;;) {
- if (sieveBuildBig(sieve, SIEVE, bn, step, 0) < 0)
- goto failed;
-
- p = prev = 0;
- if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
- do {
- /*
- * Adjust bn to have the right value,
- * adding (p-prev) * 2*step.
- */
- assert(p >= prev);
- /* Compute delta into a */
- if (bnMulQ(&a, step, p-prev) < 0)
- goto failed;
- if (bnAdd(bn, &a) < 0)
- goto failed;
- prev = p;
-
- retval = primeTest(bn, &e, &a, f, arg);
- if (retval <= 0)
- goto done; /* Success! */
- modexps += retval;
- if (f && (retval = f(arg, '.')) < 0)
- goto done;
-
- /* And try again */
- p = sieveSearch(sieve, SIEVE, p);
- } while (p);
- }
-
- /* Ran out of sieve space - increase bn and keep trying. */
-#if SIEVE*8 == 65536
- /* Corner case that will never actually happen */
- if (!prev) {
- if (bnAdd(bn, step) < 0)
- goto failed;
- p = 65535;
- } else {
- p = (unsigned)(SIEVE*8 - prev);
- }
-#else
- p = SIEVE*8 - prev;
-#endif
- if (bnMulQ(&a, step, p) < 0 || bnAdd(bn, &a) < 0)
- goto failed;
- if (f && (retval = f(arg, '/')) < 0)
- goto done;
- } /* for (;;) */
-
-failed:
- retval = -1;
-
-done:
-
- bnEnd(&e);
- bnEnd(&a);
-#ifdef MSDOS
- lbnMemFree(sieve, SIEVE);
-#else
- lbnMemWipe(sieve, sizeof(sieve));
-#endif
- return retval < 0 ? retval : modexps + CONFIRMTESTS;
-}
diff --git a/jni/libzrtp/sources/bnlib/prime.h b/jni/libzrtp/sources/bnlib/prime.h
deleted file mode 100644
index faff722..0000000
--- a/jni/libzrtp/sources/bnlib/prime.h
+++ /dev/null
@@ -1,12 +0,0 @@
-struct BigNum;
-
-/* Generate a prime >= bn. leaving the result in bn. */
-int primeGen(struct BigNum *bn, unsigned (*randfunc)(unsigned),
- int (*f)(void *arg, int c), void *arg, unsigned exponent, ...);
-
-/*
- * Generate a prime of the form bn + k*step. Step must be even and
- * bn must be odd.
- */
-int primeGenStrong(struct BigNum *bn, struct BigNum const *step,
- int (*f)(void *arg, int c), void *arg);
diff --git a/jni/libzrtp/sources/bnlib/sieve.c b/jni/libzrtp/sources/bnlib/sieve.c
deleted file mode 100644
index 7362ff5..0000000
--- a/jni/libzrtp/sources/bnlib/sieve.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * sieve.c - Trial division for prime finding.
- *
- * Copyright (c) 1995 Colin Plumb. All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * Finding primes:
- * - Sieve 1 to find the small primes for
- * - Sieve 2 to find the candidate large primes, then
- * - Pseudo-primality test.
- *
- * An important question is how much trial division by small primes
- * should we do? The answer is a LOT. Even a heavily optimized
- * Fermat test to the base 2 (the simplest pseudoprimality test)
- * is much more expensive than a division.
- *
- * For an prime of n k-bit words, a Fermat test to the base 2 requires n*k
- * modular squarings, each of which involves n*(n+1)/2 signle-word multiplies
- * in the squaring and n*(n+1) multiplies in the modular reduction, plus
- * some overhead to get into and out of Montgomery form. This is a total
- * of 3/2 * k * n^2 * (n+1). Equivalently, if n*k = b bits, it's
- * 3/2 * (b/k+1) * b^2 / k.
- *
- * A modulo operation requires n single-word divides. Let's assume that
- * a divide is 4 times the cost of a multiply. That's 4*n multiplies.
- * However, you only have to do the division once for your entire
- * search. It can be amortized over 10-15 primes. So it's
- * really more like n/3 multiplies. This is b/3k.
- *
- * Now, let's suppose you have a candidate prime t. Your options
- * are to a) do trial division by a prime p, then do a Fermat test,
- * or to do the Fermat test directly. Doing the trial division
- * costs b/3k multiplies, but a certain fraction of the time (1/p), it
- * saves you 3/2 b^3 / k^2 multiplies. Thus, it's worth it doing the
- * division as long as b/3k < 3/2 * (b/k+1) * b^2 / k / p.
- * I.e. p < 9/2 * (b/k + 1) * b = 9/2 * (b^2/k + b).
- * E.g. for k=16 and b=256, p < 9/2 * 17 * 256 = 19584.
- * Solving for k=16 and k=32 at a few interesting value of b:
- *
- * k=16, b=256: p < 19584 k=32, b=256: p < 10368
- * k=16, b=384: p < 43200 k=32, b=384; p < 22464
- * k=16, b=512: p < 76032 k=32, b=512: p < 39168
- * k=16, b=640: p < 118080 k=32, b=640: p < 60480
- *
- * H'm... before using the highly-optimized Fermat test, I got much larger
- * numbers (64K to 256K), and designed the sieve for that. Maybe it needs
- * to be reduced. It *is* true that the desirable sieve size increases
- * rapidly with increasing prime size, and it's the larger primes that are
- * worrisome in any case. I'll leave it as is (64K) for now while I
- * think about it.
- *
- * A bit of tweaking the division (we can compute a reciprocal and do
- * multiplies instead, turning 4*n into 4 + 2*n) would increase all the
- * numbers by a factor of 2 or so.
- *
- *
- * Bit k in a sieve corresponds to the number a + k*b.
- * For a given a and b, the sieve's job is to find the values of
- * k for which a + k*b == 0 (mod p). Multiplying by b^-1 and
- * isolating k, you get k == -a*b^-1 (mod p). So the values of
- * k which should be worked on are k = (-a*b^-1 mod p) + i * p,
- * for i = 0, 1, 2,...
- *
- * Note how this is still easy to use with very large b, if you need it.
- * It just requires computing (b mod p) and then finding the multiplicative
- * inverse of that.
- *
- *
- * How large a space to search to ensure that one will hit a prime?
- * The average density is known, but the primes behave oddly, and sometimes
- * there are large gaps. It is conjectured by shanks that the first gap
- * of size "delta" will occur at approximately exp(sqrt(delta)), so a delta
- * of 65536 is conjectured to be to contain a prime up to e^256.
- * Remembering the handy 2<->e conversion ratios:
- * ln(2) = 0.693147 log2(e) = 1.442695
- * This covers up to 369 bits. Damn, not enough! Still, it'll have to do.
- *
- * Cramer's conjecture (he proved it for "most" cases) is that in the limit,
- * as p goes to infinity, the largest gap after a prime p tends to (ln(p))^2.
- * So, for a 1024-bit p, the interval to the next prime is expected to be
- * about 709.78^2, or 503791. We'd need to enlarge our space by a factor of
- * 8 to be sure. It isn't worth the hassle.
- *
- * Note that a span of this size is expected to contain 92 primes even
- * in the vicinity of 2^1024 (it's 369 at 256 bits and 492 at 192 bits).
- * So the probability of failure is pretty low.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_LIMITS_H
-#define NO_LIMITS_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_LIMITS_H
-#include <limits.h> /* For UINT_MAX */
-#endif /* If not avail, default value of 0 is safe */
-
-#if !NO_STRING_H
-#include <string.h> /* for memset() */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "bn.h"
-#include "sieve.h"
-#ifdef MSDOS
-#include "lbnmem.h"
-#endif
-
-#include "kludge.h"
-
-/*
- * Each array stores potential primes as 1 bits in little-endian bytes.
- * Bit k in an array represents a + k*b, for some parameters a and b
- * of the sieve. Currently, b is hardcoded to 2.
- *
- * Various factors of 16 arise because these are all *byte* sizes, and
- * skipping even numbers, 16 numbers fit into a byte's worth of bitmap.
- */
-
-/*
- * The first number in the small prime sieve. This could be raised to
- * 3 if you want to squeeze bytes out aggressively for a smaller SMALL
- * table, and doing so would let one more prime into the end of the array,
- * but there is no sense making it larger if you're generating small
- * primes up to the limit if 2^16, since it doesn't save any memory and
- * would require extra code to ignore 65537 in the last byte, which is
- * over the 16-bit limit.
- */
-#define SMALLSTART 1
-
-/*
- * Size of sieve used to find large primes, in bytes. For compatibility
- * with 16-bit-int systems, the largest prime that can appear in it,
- * SMALL * 16 + SMALLSTART - 2, must be < 65536. Since 65537 is a prime,
- * this is the absolute maximum table size.
- */
-#define SMALL (65536/16)
-
-/*
- * Compute the multiplicative inverse of x, modulo mod, using the extended
- * Euclidean algorithm. The classical EEA returns two results, traditionally
- * named s and t, but only one (t) is needed or computed here.
- * It is unrolled twice to avoid some variable-swapping, and because negating
- * t every other round makes all the number positive and less than the
- * modulus, which makes fixed-length arithmetic easier.
- *
- * If gcd(x, mod) != 1, then this will return 0.
- */
-static unsigned
-sieveModInvert(unsigned x, unsigned mod)
-{
- unsigned y;
- unsigned t0, t1;
- unsigned q;
-
- if (x <= 1)
- return x; /* 0 and 1 are self-inverse */
- /*
- * The first round is simplified based on the
- * initial conditions t0 = 1 and t1 = 0.
- */
- t1 = mod / x;
- y = mod % x;
- if (y <= 1)
- return y ? mod - t1 : 0;
- t0 = 1;
-
- do {
- q = x / y;
- x = x % y;
- t0 += q * t1;
- if (x <= 1)
- return x ? t0 : 0;
- q = y / x;
- y = y % x;
- t1 += q * t0;
- } while (y > 1);
- return y ? mod - t1 : 0;
-}
-
-
-/*
- * Perform a single sieving operation on an array. Clear bits "start",
- * "start+step", "start+2*step", etc. from the array, up to the size
- * limit (in BYTES) "size". All of the arguments must fit into 16 bits
- * for portability.
- *
- * This is the core of the sieving operation. In addition to being
- * called from the sieving functions, it is useful to call directly if,
- * say, you want to exclude primes congruent to 1 mod 3, or whatever.
- * (Although in that case, it would be better to change the sieving to
- * use a step size of 6 and start == 5 (mod 6).)
- *
- * Originally, this was inlined in the code below (with various checks
- * turned off where they could be inferred from the environment), but it
- * turns out that all the sieving is so fast that it makes a negligible
- * speed difference and smaller, cleaner code was preferred.
- *
- * Rather than increment a bit index through the array and clear
- * the corresponding bit, this code takes advantage of the fact that
- * every eighth increment must use the same bit position in a byte.
- * I.e. start + k*step == start + (k+8)*step (mod 8). Thus, a bitmask
- * can be computed only eight times and used for all multiples. Thus, the
- * outer loop is over (k mod 8) while the inner loop is over (k div 8).
- *
- * The only further trickiness is that this code is designed to accept
- * start, step, and size up to 65535 on 16-bit machines. On such a
- * machine, the computation "start+step" can overflow, so we need to
- * insert an extra check for that situation.
- */
-void
-sieveSingle(unsigned char *array, unsigned size, unsigned start, unsigned step)
-{
- unsigned bit;
- unsigned char mask;
- unsigned i;
-
-#if UINT_MAX < 0x1ffff
- /* Unsigned is small; add checks for wrap */
- for (bit = 0; bit < 8; bit++) {
- i = start/8;
- if (i >= size)
- break;
- mask = ~(1 << (start & 7));
- do {
- array[i] &= mask;
- i += step;
- } while (i >= step && i < size);
- start += step;
- if (start < step) /* Overflow test */
- break;
- }
-#else
- /* Unsigned has the range - no overflow possible */
- for (bit = 0; bit < 8; bit++) {
- i = start/8;
- if (i >= size)
- break;
- mask = ~(1 << (start & 7));
- do {
- array[i] &= mask;
- i += step;
- } while (i < size);
- start += step;
- }
-#endif
-}
-
-/*
- * Returns the index of the next bit set in the given array. The search
- * begins after the specified bit, so if you care about bit 0, you need
- * to check it explicitly yourself. This returns 0 if no bits are found.
- *
- * Note that the size is in bytes, and that it takes and returns BIT
- * positions. If the array represents odd numbers only, as usual, the
- * returned values must be doubled to turn them into offsets from the
- * initial number.
- */
-unsigned
-sieveSearch(unsigned char const *array, unsigned size, unsigned start)
-{
- unsigned i; /* Loop index */
- unsigned char t; /* Temp */
-
- if (!++start)
- return 0;
- i = start/8;
- if (i >= size)
- return 0; /* Done! */
-
- /* Deal with odd-bit beginnings => search the first byte */
- if (start & 7) {
- t = array[i++] >> (start & 7);
- if (t) {
- if (!(t & 15)) {
- t >>= 4;
- start += 4;
- }
- if (!(t & 3)) {
- t >>= 2;
- start += 2;
- }
- if (!(t & 1))
- start += 1;
- return start;
- } else if (i == size) {
- return 0; /* Done */
- }
- }
-
- /* Now the main search loop */
-
- do {
- if ((t = array[i]) != 0) {
- start = 8*i;
- if (!(t & 15)) {
- t >>= 4;
- start += 4;
- }
- if (!(t & 3)) {
- t >>= 2;
- start += 2;
- }
- if (!(t & 1))
- start += 1;
- return start;
- }
- } while (++i < size);
-
- /* Failed */
- return 0;
-}
-
-/*
- * Build a table of small primes for sieving larger primes with. This
- * could be cached between calls to sieveBuild, but it's so fast that
- * it's really not worth it. This code takes a few milliseconds to run.
- */
-static void
-sieveSmall(unsigned char *array, unsigned size)
-{
- unsigned i; /* Loop index */
- unsigned p; /* The current prime */
-
- /* Initialize to all 1s */
- memset(array, 0xFF, size);
-
-#if SMALLSTART == 1
- /* Mark 1 as NOT prime */
- array[0] = 0xfe;
- i = 1; /* Index of first prime */
-#else
- i = 0; /* Index of first prime */
-#endif
-
- /*
- * Okay, now sieve via the primes up to 256, obtained from the
- * table itself. We know the maximum possible table size is
- * 65536, and sieveSingle() can cope with out-of-range inputs
- * safely, and the time required is trivial, so it isn't adaptive
- * based on the array size.
- *
- * Convert each bit position into a prime, compute a starting
- * sieve position (the square of the prime), and remove multiples
- * from the table, using sieveSingle(). I used to have that
- * code in line here, but the speed difference was so small it
- * wasn't worth it. If a compiler really wants to waste memory,
- * it can inline it.
- */
- do {
- p = 2 * i + SMALLSTART;
- if (p > 256)
- break;
- /* Start at square of p */
- sieveSingle(array, size, (p*p-SMALLSTART)/2, p);
-
- /* And find the next prime */
- i = sieveSearch(array, 16, i);
- } while (i);
-}
-
-
-/*
- * This is the primary sieving function. It fills in the array with
- * a sieve (multiples of small primes removed) beginning at bn and
- * proceeding in steps of "step".
- *
- * It generates a small array to get the primes to sieve by. It's
- * generated on the fly - sieveSmall is fast enough to make that
- * perfectly acceptable.
- *
- * The caller should take the array, walk it with sieveSearch, and
- * apply a stronger primality test to the numbers that are returned.
- *
- * If the "dbl" flag non-zero (at least 1), this also sieves 2*bn+1, in
- * steps of 2*step. If dbl is 2 or more, this also sieve 4*bn+3,
- * in steps of 4*step, and so on for arbitrarily high values of "dbl".
- * This is convenient for finding primes such that (p-1)/2 is also prime.
- * This is particularly efficient because sieveSingle is controlled by the
- * parameter s = -n/step (mod p). (In fact, we find t = -1/step (mod p)
- * and multiply that by n (mod p).) If you have -n/step (mod p), then
- * finding -(2*n+1)/(2*step) (mod p), which is -n/step - 1/(2*step) (mod p),
- * reduces to finding -1/(2*step) (mod p), or t/2 (mod p), and adding that
- * to s = -n/step (mod p). Dividing by 2 modulo an odd p is easy -
- * if even, divide directly. Otherwise, add p (which produces an even
- * sum), and divide by 2. Very simple. And this produces s' and t'
- * for step' = 2*step. It can be repeated for step'' = 4*step and so on.
- *
- * Note that some of the math is complicated by the fact that 2*p might
- * not fit into an unsigned, so rather than if (odd(x)) x = (x+p)/2,
- * we do if (odd(x)) x = x/2 + p/2 + 1;
- *
- * TODO: Do the double-sieving by sieving the larger number, and then
- * just subtract one from the remainder to get the other parameter.
- * (bn-1)/2 is divisible by an odd p iff bn-1 is divisible, which is
- * true iff bn == 1 mod p. This requires using a step size of 4.
- */
-int
-sieveBuild(unsigned char *array, unsigned size, struct BigNum const *bn,
- unsigned step, unsigned dbl)
-{
- unsigned i, j; /* Loop index */
- unsigned p; /* Current small prime */
- unsigned s; /* Where to start operations in the big sieve */
- unsigned t; /* Step modulo p, the current prime */
-#ifdef MSDOS /* Use dynamic allocation rather than on the stack */
- unsigned char *small;
-#else
- unsigned char small[SMALL];
-#endif
-
- assert(array);
-
-#ifdef MSDOS
- small = lbnMemAlloc(SMALL); /* Which allocator? Not secure. */
- if (!small)
- return -1; /* Failed */
-#endif
-
- /*
- * An odd step is a special case, since we must sieve by 2,
- * which isn't in the small prime array and has a few other
- * special properties. These are:
- * - Since the numbers are stored in binary, we don't need to
- * use bnModQ to find the remainder.
- * - If step is odd, then t = step % 2 is 1, which allows
- * the elimination of a lot of math. Inverting and negating
- * t don't change it, and multiplying s by 1 is a no-op,
- * so t isn't actually mentioned.
- * - Since this is the first sieving, instead of calling
- * sieveSingle, we can just use memset to fill the array
- * with 0x55 or 0xAA. Since a 1 bit means possible prime
- * (i.e. NOT divisible by 2), and the least significant bit
- * is first, if bn % 2 == 0, we use 0xAA (bit 0 = bn is NOT
- * prime), while if bn % 2 == 1, use 0x55.
- * (If step is even, bn must be odd, so fill the array with 0xFF.)
- * - Any doublings need not be considered, since 2*bn+1 is odd, and
- * 2*step is even, so none of these numbers are divisible by 2.
- */
- if (step & 1) {
- s = bnLSWord(bn) & 1;
- memset(array, 0xAA >> s, size);
- } else {
- /* Initialize the array to all 1's */
- memset(array, 255, size);
- assert(bnLSWord(bn) & 1);
- }
-
- /*
- * This could be cached between calls to sieveBuild, but
- * it's really not worth it; sieveSmall is *very* fast.
- * sieveSmall returns a sieve of odd primes.
- */
- sieveSmall(small, SMALL);
-
- /*
- * Okay, now sieve via the primes up to ssize*16+SMALLSTART-1,
- * obtained from the small table.
- */
- i = (small[0] & 1) ? 0 : sieveSearch(small, SMALL, 0);
- do {
- p = 2 * i + SMALLSTART;
-
- /*
- * Modulo is usually very expensive, but step is usually
- * small, so this conditional is worth it.
- */
- t = (step < p) ? step : step % p;
- if (!t) {
- /*
- * Instead of assert failing, returning all zero
- * bits is the "correct" thing to do, but I think
- * that the caller should take care of that
- * themselves before starting.
- */
- assert(bnModQ(bn, p) != 0);
- continue;
- }
- /*
- * Get inverse of step mod p. 0 < t < p, and p is prime,
- * so it has an inverse and sieveModInvert can't return 0.
- */
- t = sieveModInvert(t, p);
- assert(t);
- /* Negate t, so now t == -1/step (mod p) */
- t = p - t;
-
- /* Now get the bignum modulo the prime. */
- s = bnModQ(bn, p);
-
- /* Multiply by t, the negative inverse of step size */
-#if UINT_MAX/0xffff < 0xffff
- s = (unsigned)(((unsigned long)s * t) % p);
-#else
- s = (s * t) % p;
-#endif
-
- /* s is now the starting bit position, so sieve */
- sieveSingle(array, size, s, p);
-
- /* Now do the double sieves as desired. */
- for (j = 0; j < dbl; j++) {
- /* Halve t modulo p */
-#if UINT_MAX < 0x1ffff
- t = (t & 1) ? p/2 + t/2 + 1 : t/2;
- /* Add t to s, modulo p with overflow checks. */
- s += t;
- if (s >= p || s < t)
- s -= p;
-#else
- if (t & 1)
- t += p;
- t /= 2;
- /* Add t to s, modulo p */
- s += t;
- if (s >= p)
- s -= p;
-#endif
- sieveSingle(array, size, s, p);
- }
-
- /* And find the next prime */
- } while ((i = sieveSearch(small, SMALL, i)) != 0);
-
-#ifdef MSDOS
- lbnMemFree(small, SMALL);
-#endif
- return 0; /* Success */
-}
-
-/*
- * Similar to the above, but use "step" (which must be even) as a step
- * size rather than a fixed value of 2. If "step" has any small divisors
- * other than 2, this will blow up.
- *
- * Returns -1 on out of memory (MSDOS only, actually), and -2
- * if step is found to be non-prime.
- */
-int
-sieveBuildBig(unsigned char *array, unsigned size, struct BigNum const *bn,
- struct BigNum const *step, unsigned dbl)
-{
- unsigned i, j; /* Loop index */
- unsigned p; /* Current small prime */
- unsigned s; /* Where to start operations in the big sieve */
- unsigned t; /* step modulo p, the current prime */
-#ifdef MSDOS /* Use dynamic allocation rather than on the stack */
- unsigned char *small;
-#else
- unsigned char small[SMALL];
-#endif
-
- assert(array);
-
-#ifdef MSDOS
- small = lbnMemAlloc(SMALL); /* Which allocator? Not secure. */
- if (!small)
- return -1; /* Failed */
-#endif
- /*
- * An odd step is a special case, since we must sieve by 2,
- * which isn't in the small prime array and has a few other
- * special properties. These are:
- * - Since the numbers are stored in binary, we don't need to
- * use bnModQ to find the remainder.
- * - If step is odd, then t = step % 2 is 1, which allows
- * the elimination of a lot of math. Inverting and negating
- * t don't change it, and multiplying s by 1 is a no-op,
- * so t isn't actually mentioned.
- * - Since this is the first sieving, instead of calling
- * sieveSingle, we can just use memset to fill the array
- * with 0x55 or 0xAA. Since a 1 bit means possible prime
- * (i.e. NOT divisible by 2), and the least significant bit
- * is first, if bn % 2 == 0, we use 0xAA (bit 0 = bn is NOT
- * prime), while if bn % 2 == 1, use 0x55.
- * (If step is even, bn must be odd, so fill the array with 0xFF.)
- * - Any doublings need not be considered, since 2*bn+1 is odd, and
- * 2*step is even, so none of these numbers are divisible by 2.
- */
- if (bnLSWord(step) & 1) {
- s = bnLSWord(bn) & 1;
- memset(array, 0xAA >> s, size);
- } else {
- /* Initialize the array to all 1's */
- memset(array, 255, size);
- assert(bnLSWord(bn) & 1);
- }
-
- /*
- * This could be cached between calls to sieveBuild, but
- * it's really not worth it; sieveSmall is *very* fast.
- * sieveSmall returns a sieve of the odd primes.
- */
- sieveSmall(small, SMALL);
-
- /*
- * Okay, now sieve via the primes up to ssize*16+SMALLSTART-1,
- * obtained from the small table.
- */
- i = (small[0] & 1) ? 0 : sieveSearch(small, SMALL, 0);
- do {
- p = 2 * i + SMALLSTART;
-
- t = bnModQ(step, p);
- if (!t) {
- assert(bnModQ(bn, p) != 0);
- continue;
- }
- /* Get negative inverse of step */
- t = sieveModInvert(bnModQ(step, p), p);
- assert(t);
- t = p-t;
-
- /* Okay, we have a prime - get the remainder */
- s = bnModQ(bn, p);
-
- /* Now multiply s by the negative inverse of step (mod p) */
-#if UINT_MAX/0xffff < 0xffff
- s = (unsigned)(((unsigned long)s * t) % p);
-#else
- s = (s * t) % p;
-#endif
- /* We now have the starting bit pos */
- sieveSingle(array, size, s, p);
-
- /* Now do the double sieves as desired. */
- for (j = 0; j < dbl; j++) {
- /* Halve t modulo p */
-#if UINT_MAX < 0x1ffff
- t = (t & 1) ? p/2 + t/2 + 1 : t/2;
- /* Add t to s, modulo p with overflow checks. */
- s += t;
- if (s >= p || s < t)
- s -= p;
-#else
- if (t & 1)
- t += p;
- t /= 2;
- /* Add t to s, modulo p */
- s += t;
- if (s >= p)
- s -= p;
-#endif
- sieveSingle(array, size, s, p);
- }
-
- /* And find the next prime */
- } while ((i = sieveSearch(small, SMALL, i)) != 0);
-
-#ifdef MSDOS
- lbnMemFree(small, SMALL);
-#endif
- return 0; /* Success */
-}
diff --git a/jni/libzrtp/sources/bnlib/sieve.h b/jni/libzrtp/sources/bnlib/sieve.h
deleted file mode 100644
index 22ed6ce..0000000
--- a/jni/libzrtp/sources/bnlib/sieve.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * sieve.h - Trial division for prime finding.
- *
- * This is generally not intended for direct use by a user of the library;
- * the prime.c and dhprime.c functions. are more likely to be used.
- * However, a special application may need these.
- */
-struct BigNum;
-
-/* Remove multiples of a single number from the sieve */
-void
-sieveSingle(unsigned char *array, unsigned size, unsigned start, unsigned step);
-
-/* Build a sieve starting at the number and incrementing by "step". */
-int sieveBuild(unsigned char *array, unsigned size, struct BigNum const *bn,
- unsigned step, unsigned dbl);
-
-/* Similar, but uses a >16-bit step size */
-int sieveBuildBig(unsigned char *array, unsigned size, struct BigNum const *bn,
- struct BigNum const *step, unsigned dbl);
-
-/* Return the next bit set in the sieve (or 0 on failure) */
-unsigned sieveSearch(unsigned char const *array, unsigned size, unsigned start);
diff --git a/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake b/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
index 506b224..43a3d11 100644
--- a/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
+++ b/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
@@ -23,7 +23,7 @@
# others
"\\\\.#"
"/#"
- "/build*"
+ "/build/"
"/autom4te\\\\.cache/"
"/_build/"
"/doc/html/"
@@ -37,9 +37,6 @@
"\\\\.la$"
"\\\\.sh$"
"Makefile\\\\.in$"
- "\\\\.directory$"
- "\\\\._.DS_Store$"
- "\\\\._buildmac$"
)
SET(CPACK_PACKAGE_VENDOR "Werner Dittmann")
@@ -55,20 +52,24 @@
# SPECFILE()
- ADD_CUSTOM_TARGET(svncheck
- COMMAND cd $(CMAKE_SOURCE_DIR) && LC_ALL=C git status | grep -q "nothing to commit .working directory clean.")
+ ADD_CUSTOM_TARGET( svncheck
+ COMMAND cd $(CMAKE_SOURCE_DIR) && LC_ALL=C git status | grep -q "nothing to commit .working directory clean."
+ )
- SET(AUTOBUILD_COMMAND
- COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/*.tar.bz2
+ SET( AUTOBUILD_COMMAND
+ COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/package/*.tar.bz2
COMMAND ${CMAKE_MAKE_PROGRAM} package_source
+ COMMAND ${CMAKE_COMMAND} -E copy ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2 ${CMAKE_BINARY_DIR}/package
+ COMMAND ${CMAKE_COMMAND} -E remove ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2
# COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/package/${PACKAGE}.changes" "${CMAKE_BINARY_DIR}/package/${PACKAGE}.changes"
)
- ADD_CUSTOM_TARGET(srcpackage_local
- ${AUTOBUILD_COMMAND})
+ ADD_CUSTOM_TARGET( srcpackage_local
+ ${AUTOBUILD_COMMAND}
+ )
- ADD_CUSTOM_TARGET(srcpackage
- COMMAND ${CMAKE_MAKE_PROGRAM} svncheck
- ${AUTOBUILD_COMMAND})
-
- ENDMACRO(GENERATE_PACKAGING)
+ ADD_CUSTOM_TARGET( srcpackage
+ COMMAND ${CMAKE_MAKE_PROGRAM} svncheck
+ ${AUTOBUILD_COMMAND}
+ )
+ENDMACRO(GENERATE_PACKAGING)
diff --git a/jni/libzrtp/sources/common/EventClass.cpp b/jni/libzrtp/sources/common/EventClass.cpp
deleted file mode 100644
index bfe117f9..0000000
--- a/jni/libzrtp/sources/common/EventClass.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-//
-// EventClass.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement event signals as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 11/02/07
-// Name: Walter E. Capers
-// Description: removed unnessary code identified by On Freund from Code Project
-//
-//
-#include "Thread.h"
-
-#ifndef WINDOWS
-#include <sys/time.h>
-#endif
-
-#include <iostream>
-using namespace std;
-
-CEventClass::CEventClass(void)
-:m_bCreated(TRUE)
-{
- memset(&m_owner,0,sizeof(ThreadId_t));
-#ifdef WINDOWS
- m_event = CreateEvent(NULL,FALSE,FALSE,NULL);
- if( !m_event )
- {
- m_bCreated = FALSE;
- }
-#else
- pthread_mutexattr_t mattr;
-
- pthread_mutexattr_init(&mattr);
- pthread_mutex_init(&m_lock,&mattr);
- pthread_cond_init(&m_ready,NULL);
-
-#endif
-}
-
-CEventClass::~CEventClass(void)
-{
-#ifdef WINDOWS
- CloseHandle(m_event);
-#else
- pthread_cond_destroy(&m_ready);
- pthread_mutex_destroy(&m_lock);
-#endif
-}
-
-
-/**
- *
- * Set
- * set an event to signaled
- *
- **/
-void
-CEventClass::Set()
-{
-#ifdef WINDOWS
- SetEvent(m_event);
-#else
- pthread_cond_signal(&m_ready);
-#endif
-}
-
-/**
- *
- * Wait
- * wait for an event -- wait for an event object
- * to be set to signaled. must be paired with a
- * call to reset within the same thread.
- *
- **/
-BOOL
-CEventClass::Wait(DWORD tmout)
-{
-
- try
- {
- ThreadId_t id = CThread::ThreadId();
- if( CThread::ThreadIdsEqual(&id,&m_owner) )
- {
- throw "\n\tinvalid Wait call, Wait can not be called more than once"
- "\n\twithout a corresponding call to Reset!\n";
- }
- ThreadId_t zero;
- memset(&zero,0,sizeof(ThreadId_t));
-
- if( memcmp(&zero,&m_owner,sizeof(ThreadId_t)) != 0 )
- {
- throw "\n\tanother thread is already waiting on this event!\n";
- }
-
- m_owner = CThread::ThreadId();
-#ifdef WINDOWS
- tmout = tmout == 0 ? INFINITE : tmout;
- DWORD rc = WaitForSingleObject(m_event, tmout);
- e_timeout = FALSE;
- if (rc == WAIT_OBJECT_0) {
- return TRUE;
- }
- else if (rc == WAIT_TIMEOUT) {
- e_timeout = TRUE;
- return TRUE;
- }
- else
- return FALSE;
-#else
- pthread_mutex_lock(&m_lock);
- e_timeout = FALSE;
- if (tmout == 0) {
- pthread_cond_wait(&m_ready,&m_lock);
- return TRUE;
- }
- struct timespec ts;
- timeval tv;
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000l;
- ts.tv_sec += tmout / 1000;
- ts.tv_nsec += (tmout % 1000) * 1000000l;
- while(ts.tv_nsec > 1000000000l) {
- ++ts.tv_sec;
- ts.tv_nsec -= 1000000000l;
- }
- int rc = pthread_cond_timedwait(&m_ready, &m_lock, &ts);
- if (rc == ETIMEDOUT)
- e_timeout = TRUE;
- return TRUE;
-#endif
- }
- catch( char *psz )
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CEventClass::Wait",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CEventClass::Wait: " << psz;
-#endif
-
- }
- return TRUE;
-}
-
-
-/**
- *
- * Reset
- * reset an event flag to unsignaled
- * wait must be paired with reset within the same thread.
- *
- **/
-void
-CEventClass::Reset()
-{
- try
- {
- ThreadId_t id = CThread::ThreadId();
- if( !CThread::ThreadIdsEqual(&id,&m_owner) )
- {
- throw "\n\tunbalanced call to Reset, Reset must be called from\n"
- "\n\tthe same Wait-Reset pair!\n";
- }
-
- memset(&m_owner,0,sizeof(ThreadId_t));
-
-#ifndef WINDOWS
- pthread_mutex_unlock(&m_lock);
-#endif
- }
- catch( char *psz )
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CEventClass::Reset",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CEventClass::Reset: " << psz;
-#endif
-
- }
-}
-
diff --git a/jni/libzrtp/sources/common/EventClass.h b/jni/libzrtp/sources/common/EventClass.h
deleted file mode 100644
index d9a15e7..0000000
--- a/jni/libzrtp/sources/common/EventClass.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// EventClass.h: header file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement event signals as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-#ifndef EVENT_CLASS
-#define EVENT_CLASS
-
-class CEventClass
-{
-private:
- ThreadId_t m_owner;
-#ifdef WINDOWS
- HANDLE m_event;
-#else
- pthread_cond_t m_ready;
- pthread_mutex_t m_lock;
-#endif
-public:
- BOOL e_timeout;
- BOOL m_bCreated;
- void Set();
- BOOL Wait(DWORD tmout =0);
- void Reset();
- CEventClass(void);
- ~CEventClass(void);
-};
-
-#endif
-
diff --git a/jni/libzrtp/sources/common/MutexClass.cpp b/jni/libzrtp/sources/common/MutexClass.cpp
deleted file mode 100644
index ebf8e4e..0000000
--- a/jni/libzrtp/sources/common/MutexClass.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// MutexClass.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement mutexes as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-#include "Thread.h"
-
-#include <iostream>
-using namespace std;
-
-CMutexClass::CMutexClass(void)
-:m_bCreated(TRUE)
-{
-#ifdef WINDOWS
- m_mutex = CreateMutex(NULL,FALSE,NULL);
- if( !m_mutex ) m_bCreated = FALSE;
-#else
- pthread_mutexattr_t mattr;
-
- pthread_mutexattr_init( &mattr );
- pthread_mutex_init(&m_mutex,&mattr);
-
-#endif
- memset(&m_owner,0,sizeof(ThreadId_t));
-
-}
-
-CMutexClass::~CMutexClass(void)
-{
-#ifdef WINDOWS
- WaitForSingleObject(m_mutex,INFINITE);
- CloseHandle(m_mutex);
-#else
- pthread_mutex_lock(&m_mutex);
- pthread_mutex_unlock(&m_mutex);
- pthread_mutex_destroy(&m_mutex);
-#endif
-}
-
-/**
- *
- * Lock
- * the same thread can not lock the same mutex
- * more than once
- *
- **/
-void
-CMutexClass::Lock()
-{
- ThreadId_t id = CThread::ThreadId();
- try {
- if(CThread::ThreadIdsEqual(&m_owner,&id) )
- throw "\n\tthe same thread can not acquire a mutex twice!\n"; // the mutex is already locked by this thread
-#ifdef WINDOWS
- WaitForSingleObject(m_mutex,INFINITE);
-#else
- pthread_mutex_lock(&m_mutex);
-#endif
- m_owner = CThread::ThreadId();
- }
- catch( char *psz )
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CMutexClass::Lock",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CMutexClass::Lock : " << psz;
-#endif
-
-
- }
-
-}
-
-/**
- *
- * Unlock
- * releases a mutex. only the thread that acquires
- * the mutex can release it.
- *
- **/
-void
-CMutexClass::Unlock()
-{
- ThreadId_t id = CThread::ThreadId();
- try
- {
- if( ! CThread::ThreadIdsEqual(&id,&m_owner) )
- throw "\n\tonly the thread that acquires a mutex can release it!";
-
- memset(&m_owner,0,sizeof(ThreadId_t));
-#ifdef WINDOWS
- ReleaseMutex(m_mutex);
-#else
- pthread_mutex_unlock(&m_mutex);
-#endif
- }
- catch ( char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CMutexClass::Unlock",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CMutexClass::Unlock : " << psz;
-#endif
-
- }
-}
-
diff --git a/jni/libzrtp/sources/common/MutexClass.h b/jni/libzrtp/sources/common/MutexClass.h
deleted file mode 100644
index a3600f4..0000000
--- a/jni/libzrtp/sources/common/MutexClass.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// MutexClass.h: header file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement mutexes as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-
-#ifndef MUTEX_CLASS
-#define MUTEX_CLASS
-
-#ifndef WINDOWS
-#if defined(WIN32) || defined(WIN64)
-#define WINDOWS
-#endif
-#endif
-
-#ifndef WINDOWS
-#include <pthread.h>
-#endif
-#include <common/Thread.h>
-
-class CMutexClass
-{
-private:
-#ifdef WINDOWS
- HANDLE m_mutex;
-#else
- pthread_mutex_t m_mutex;
-#endif
- ThreadId_t m_owner;
-public:
- BOOL m_bCreated;
- void Lock();
- void Unlock();
- CMutexClass(void);
- ~CMutexClass(void);
-};
-#endif
-
diff --git a/jni/libzrtp/sources/common/Thread.cpp b/jni/libzrtp/sources/common/Thread.cpp
deleted file mode 100644
index 1bec1f0..0000000
--- a/jni/libzrtp/sources/common/Thread.cpp
+++ /dev/null
@@ -1,1129 +0,0 @@
-//
-// Thread.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email your changes
-// to walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement threading as a C++ object
-//
-// NOTES:
-// This object supports two types of thread models, event driven and
-// interval driven. Under the event driven model, a thread waits
-// in a paused state until the member function Event is called. When
-// the Event function is called the thread wakes up and calls OnTask.
-// Under the interval driven model, the thread wakes up every
-// m_dwIdle milli-seconds and calls OnTask.
-//
-// You can switch between the two models from within the same object.
-//
-// COMPILER NOTES:
-// On Unix you must use -lpthread a -lrt
-// On Windows you must specify threaded under C++ code generation
-//
-// REVISIONS
-// =======================================================
-// Date: 10.24.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 10.24.07 11:49 am
-// Name: Walter E. Capers
-// Description: Added SetIdle function to allow the idle time to be altered
-// independent of the SetThreadType member function.
-// Added sleep interval to Stop function.
-//
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: Added support for other non-windows platforms.
-//
-// Added static functions: ThreadIdsEqual and ThreadId.
-//
-// Added que for handling multiple events.
-//
-// Created the CEventClass and CMutexClass classes to facilitate
-// platform independence.
-//
-// Date: 10.26.07
-// Name: Walter E. Capers
-// Description: Made object production ready...
-// Added more comments
-//
-// Addressed various issues with threads on UNIX systems.
-// -- there was a defect in the Sleep function
-// -- there was a defect in the main thread function THKERNEL
-// , when transitioning between thread models the CEvent::Reset
-// function was not being called when it was necessary resulting
-// in a lock up.
-//
-// Transition between thread types also failed on WINDOWS since the Event
-// member function was being called from within SetThreadType. This
-// resulted in an Event usage error. To correct the problem m_event.Set
-// is called instead. Also, eliminated unecessary logic.
-//
-// Got rid of OnStart, OnStop, OnDestroy... Could not override with a derived
-// class, not sure why I will come back to in a later release.
-//
-// Changed default behavior of thread. If OnTask is not redefined in the derived
-// class the default version now expects a CTask object. The Class for CTask
-// is defined in thread.h. A class must be derived from CTask to use it in
-// the default version of OnTask(LPVOID).
-//
-// Date: 11.01.07
-// Name: Walter E. Capers
-// Description: I introduced more logic and ASSERTIONS to insure the integrity of CThread objects.
-// Both the Homogeneous and Specialized thread types can be physically set using the
-// SetThreadType member function. If the thread type is not set, the thread will
-// determine its type based on calls to member functions; however, this does not
-// apply to interval-based threads. Interval-based threads must be implicitly
-// identified using the SetThreadType member function. The new integrity tests
-// are implemented to insure usage consistency with a CThread object.
-//
-// New member functions AtCapacity and PercentCapacity were added to determine
-// if a thread is truly busy. AtCapacity will return TRUE under one of two
-// conditions: the thread is processing an event and its stack is full, the thread
-// is not running. These new functions allow thread objects to be placed in arrays
-// and tasked based on their workloads.
-//
-// The Event member function has been modified to verify that a thread is running
-// before posting an event. This resolved a problem on SunOS were threads did not
-// start right away; there was a small delay of a few milliseconds.
-//
-// Error flags are automatically reset when certain member functions are called this
-// isolates error occurrences to specific call sequences.
-//
-//
-// Date: 11.01.07
-// Name: Walter E. Capers
-// Description: In THKernel, changed how events are released. Events are now released right after
-// They are recieved.
-
-#include "Thread.h"
-#ifdef USE_BEGIN_THREAD
-#include <process.h>
-#endif
-
-
-
-#ifndef WINDOWS
-
-#include <unistd.h>
-#include <pthread.h>
-
-extern "C"
-{
- //int usleep(useconds_t useconds);
-#ifdef NANO_SECOND_SLEEP
- int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
-#endif
-}
-
-void Sleep( unsigned int milli )
-{
-#ifdef NANO_SECOND_SLEEP
- struct timespec interval, remainder;
- milli = milli * 1000000;
- interval.tv_sec= 0;
- interval.tv_nsec=milli;
- nanosleep(&interval,&remainder);
-#else
- usleep(milli*1000);
-#endif
-}
-#endif
-
-#include <iostream>
-using namespace std;
-
-/**
- *
- * _THKERNEL
- * thread callback function used by CreateThread
- *
- *
- **/
-#ifdef WINDOWS
-#ifdef USE_BEGIN_THREAD
-unsigned __stdcall
-#else
-DWORD WINAPI
-#endif
-#else
-LPVOID
-#endif
-_THKERNEL( LPVOID lpvData /* CThread Object */
- )
-{
- CThread *pThread = (CThread *)lpvData;
- ThreadType_t lastType;
- /*
- *
- * initialization
- *
- */
-
-
- pThread->m_mutex.Lock();
- pThread->m_state = ThreadStateWaiting;
- pThread->m_bRunning = TRUE;
-#ifndef WINDOWS
- pThread->m_dwId = CThread::ThreadId();
-#endif
- pThread->m_mutex.Unlock();
-
- while( TRUE )
- {
- lastType = pThread->m_type;
-
- if( lastType == ThreadTypeHomogeneous ||
- lastType == ThreadTypeSpecialized ||
- lastType == ThreadTypeNotDefined )
- {
- if( ! pThread->m_event.Wait() ) // wait for a message
- break;
- pThread->m_event.Reset(); // message recieved
- }
-
- if( ! pThread->KernelProcess() )
- break;
-
-
- /*if( lastType == ThreadTypeHomogeneous ||
- lastType == ThreadTypeSpecialized ||
- lastType == ThreadTypeNotDefined )
- {
- pThread->m_event.Reset();
- } */
-
- if( pThread->m_type == ThreadTypeIntervalDriven )
- Sleep(pThread->m_dwIdle);
-
- }
-
-
- pThread->m_mutex.Lock();
- pThread->m_state = ThreadStateDown;
- pThread->m_bRunning = FALSE;
- pThread->m_mutex.Unlock();
-
-
-#ifdef WINDOWS
- return 0;
-#else
- return (LPVOID)0;
-#endif
-}
-
-/**
- *
- * FromSameThread
- * determines if the calling thread is the same
- * as the thread assoicated with the object
- *
- **/
-BOOL
-CThread::FromSameThread()
-{
- ThreadId_t id = ThreadId();
- if( ThreadIdsEqual(&id,&m_dwId) ) return TRUE;
- return FALSE;
-}
-
-/**
- *
- * OnTask
- * called when a thread is tasked using the Event
- * member function
- *
- **/
-BOOL
-CThread::OnTask( LPVOID lpvData /*data passed from thread*/
- )
-{
- ASSERT(lpvData && m_type == ThreadTypeHomogeneous);
-
- if( m_type != ThreadTypeHomogeneous )
- {
- cerr << "Warning CThread::OnTask:\n\tOnTask(LPVOID) called for a non-homogeneous thread!\n";
- return FALSE;
- }
-
- ((CTask *)lpvData)->SetTaskStatus(TaskStatusBeingProcessed);
- BOOL bReturn = ((CTask *)lpvData)->Task();
- ((CTask *)lpvData)->SetTaskStatus(TaskStatusCompleted);
-
- return bReturn;
-}
-
-
-
-/**
- *
- * OnTask
- * overloaded implementation of OnTask that
- * takes no arguments
- *
- **/
-BOOL
-CThread::OnTask()
-{
- ASSERT(m_type == ThreadTypeIntervalDriven);
- if( m_type != ThreadTypeIntervalDriven )
- {
- cerr << "Warning CThread::OnTask:\n\tOnTask() called for a non-event driven thread!\n";
- return FALSE;
- }
-
- printf("\nthread is alive\n");
-
- return TRUE;
-}
-
-/**
- *
- * CEvent
- * used to place tasks on the threads event queue
- * wakes up thread.
- *
- **/
-BOOL
-CThread::Event(CTask *pvTask /* data to be processed by thread */
- )
-{
- m_mutex.Lock();
-
- ASSERT(m_type == ThreadTypeHomogeneous ||
- m_type == ThreadTypeNotDefined );
-
- try
- {
- if( FromSameThread() )
- {
- throw "\n\tit is illegal for a thread to place an event on its own event stack!\n";
- }
-
-
- // make sure that the thread is running
- if( !m_bRunning && m_dwObjectCondition == NO_ERRORS )
- {
- m_mutex.Unlock();
- PingThread(m_dwIdle*2); // wait two idle cycles for it to start
- m_mutex.Lock();
- }
- if( !m_bRunning ) // if it is not running return FALSE;
- {
- m_mutex.Unlock();
- return FALSE;
- }
-
-
- if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
- m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
- if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)
- m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
- if( m_type != ThreadTypeHomogeneous &&
- m_type != ThreadTypeNotDefined )
- {
- m_mutex.Unlock();
- m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
- m_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;
- m_state = ThreadStateFault;
- cerr << "Warning: invalid call to CEvent::Event(CTask *), thread type is not specialized\n";
-
- return FALSE;
- }
-
- m_type = ThreadTypeHomogeneous;
- m_mutex.Unlock();
-
- pvTask->SetId(&m_dwId);
- if( ! Push((LPVOID)pvTask) )
- return FALSE;
-
- pvTask->SetTaskStatus(TaskStatusWaitingOnQueue);
- m_event.Set();
-
- }
- catch (char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::CEvent",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::CEvent(CTask *pvTask):" << psz;
-#endif
-
- }
- return TRUE;
-}
-
-/**
- *
- * Event
- * used to place tasks on the threads event queue
- * wakes up thread.
- *
- **/
-BOOL
-CThread::Event(LPVOID lpvData /* data to be processed by thread */
- )
-{
-
- m_mutex.Lock();
- ASSERT( m_type == ThreadTypeSpecialized ||
- m_type == ThreadTypeNotDefined );
- try
- {
- if( FromSameThread() )
- {
- throw "\n\tit is illegal for a thread to place an event on its own event stack!\n";
- }
- }
- catch (char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::CEvent",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::CEvent(LPVOID lpvData):" << psz;
-#endif
-
- }
-
- // make sure that the thread is running
- if( !m_bRunning && m_dwObjectCondition == NO_ERRORS )
- {
- m_mutex.Unlock();
- PingThread(m_dwIdle*2); // wait two idle cycles for it to start
- m_mutex.Lock();
- }
- if( !m_bRunning ) // if it is not running return FALSE;
- {
- m_mutex.Unlock();
- return FALSE;
- }
-
- if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
- m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
- if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)
- m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
- if( m_type != ThreadTypeSpecialized &&
- m_type != ThreadTypeNotDefined )
- {
- m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
- m_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;
- cerr << "Warning: invalid call to CEvent::Event(LPVOID), thread type is not specialized\n";
- m_mutex.Unlock();
- return FALSE;
- }
- m_type = ThreadTypeSpecialized;
-
- m_mutex.Unlock();
- if( ! Push(lpvData) )
- {
- return FALSE;
- }
-
- m_event.Set();
-
- return TRUE;
-}
-
-
-/**
- *
- * SetPriority
- * sets a threads run priority, see SetThreadPriority
- * Note: only works for Windows family of operating systems
- *
- *
- **/
-void
-CThread::SetPriority(DWORD dwPriority)
-{
-
-#ifdef WINDOWS
- SetThreadPriority(m_thread,dwPriority);
-#endif
-}
-
-
-/**
- *
- * KernelProcess
- * routes thread activity
- *
- **/
-BOOL
-CThread::KernelProcess()
-{
-
- m_mutex.Lock();
- m_state = ThreadStateBusy;
- if( !m_bRunning )
- {
- m_state = ThreadStateShuttingDown;
- m_mutex.Unlock();
- return FALSE;
- }
- m_mutex.Unlock();
-
- if( !Empty() )
- {
- while( !Empty() )
- {
- Pop();
- if( !OnTask(m_lpvProcessor) )
- {
- m_mutex.Lock();
- m_lpvProcessor = NULL;
- m_state = ThreadStateShuttingDown;
- m_mutex.Unlock();
- return FALSE;
- }
- }
- m_mutex.Lock();
- m_lpvProcessor = NULL;
- m_state = ThreadStateWaiting;
- }
- else {
- if( !OnTask() )
- {
- m_mutex.Lock();
- m_state = ThreadStateShuttingDown;
- m_mutex.Unlock();
- return FALSE;
- }
- m_mutex.Lock();
- m_state = ThreadStateWaiting;
- }
-
- m_mutex.Unlock();
-
- return TRUE;
-}
-
-
-/**
- *
- * GetEventsPending
- * returns the total number of vents waiting
- * in the event que
- *
- **/
-unsigned int
-CThread::GetEventsPending()
-{
- unsigned int chEventsWaiting;
-
- m_mutex.Lock();
- chEventsWaiting = m_queuePos;
- m_mutex.Unlock();
-
- return chEventsWaiting;
-}
-
-
-/**
- *
- * CThread
- * instanciates thread object and
- * starts thread.
- *
- **/
-CThread::CThread(void)
-:m_bRunning(FALSE)
-#ifdef WINDOWS
-,m_thread(NULL)
-#endif
-,m_dwId(0L)
-,m_state(ThreadStateDown)
-,m_dwIdle(100)
-,m_lppvQueue(NULL)
-,m_lpvProcessor(NULL)
-,m_chQueue(QUEUE_SIZE)
-,m_type(ThreadTypeNotDefined)
-,m_stackSize(DEFAULT_STACK_SIZE)
-,m_queuePos(0)
-,m_StopTimeout(30)
-{
-
- m_dwObjectCondition = NO_ERRORS;
-
- m_lppvQueue = new LPVOID [QUEUE_SIZE];
-
- if( !m_lppvQueue )
- {
- m_dwObjectCondition |= MEMORY_FAULT;
- m_state = ThreadStateFault;
- return;
- }
-
- if( !m_mutex.m_bCreated )
- {
- perror("mutex creation failed");
- m_dwObjectCondition |= MUTEX_CREATION;
- m_state = ThreadStateFault;
- return;
- }
-
-
- if( !m_event.m_bCreated )
- {
- perror("event creation failed");
- m_dwObjectCondition |= EVENT_CREATION;
- m_state = ThreadStateFault;
- return;
- }
-
-
- Start();
-
-}
-
-
-/**
- *
- * PercentCapacity
- * returns a floating point value identifying
- * the current workload of the thread
- *
- **/
-float
-CThread::PercentCapacity()
-{
- float fValue = 0;
- m_mutex.Lock();
- fValue = (float)m_queuePos/m_chQueue;
- m_mutex.Unlock();
- return fValue;
-}
-
-/**
- *
- * SetQueueSize
- * changes the threads queue size
- *
- **/
-BOOL
-CThread::SetQueueSize( unsigned int ch )
-{
- LPVOID * newQueue = NULL;
-
- m_mutex.Lock();
- ASSERT(ch > m_queuePos);
-
- if( ch <= m_queuePos )
- {
- cerr << "Warning CThread::SetQueueSize:\n\tthe new queue size is less than the number of tasks on a non-empty queue! Request ignored.\n";
- m_mutex.Unlock();
- return FALSE;
- }
-
- newQueue = new LPVOID [ch];
- if( !newQueue )
- {
- cerr << "Warning CThread::SetQueueSize:\n\ta low memory, could not reallocate queue!\n";
- m_mutex.Unlock();
- return FALSE;
- }
-
- for( unsigned int i=0;i<m_queuePos; i++ )
- {
- newQueue[i] = m_lppvQueue[i];
- }
-
- delete [] m_lppvQueue;
-
- m_chQueue = ch;
- m_lppvQueue = newQueue;
-
- m_mutex.Unlock();
-
- return TRUE;
-}
-
-
-
-/**
- *
- * Empty
- * returns a value of TRUE if there are no items on the threads que
- * otherwise a value of FALSE is returned.
- *
- **/
-BOOL
-CThread::Empty()
-{
- m_mutex.Lock();
- if( m_queuePos <= 0 )
- {
- m_mutex.Unlock();
- return TRUE;
- }
- m_mutex.Unlock();
- return FALSE;
-}
-
-
-
-/**
- *
- * Push
- * place a data object in the threads que
- *
- **/
-BOOL
-CThread::Push( LPVOID lpv )
-{
- if( !lpv ) return TRUE;
-
- m_mutex.Lock();
-
- if( m_queuePos+1 >= m_chQueue ) {
- m_dwObjectCondition |= STACK_OVERFLOW;
- m_mutex.Unlock();
- return FALSE;
- }
- if( m_dwObjectCondition & STACK_EMPTY )
- m_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;
-
- if( m_dwObjectCondition & STACK_OVERFLOW )
- m_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;
-
- m_lppvQueue[m_queuePos++] = lpv;
- if( m_queuePos+1 >= m_chQueue )
- m_dwObjectCondition |= STACK_FULL;
-
- m_mutex.Unlock();
- return TRUE;
-}
-
-
-/**
- *
- * Pop
- * move an object from the input que to the processor
- *
- **/
-BOOL
-CThread::Pop()
-{
-
- m_mutex.Lock();
- if( m_queuePos-1 < 0 )
- {
- m_queuePos = 0;
- m_dwObjectCondition |= STACK_EMPTY;
- m_mutex.Unlock();
- return FALSE;
- }
- if( m_dwObjectCondition & STACK_EMPTY )
- m_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;
- if( m_dwObjectCondition & STACK_OVERFLOW )
- m_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;
- if( m_dwObjectCondition & STACK_FULL )
- m_dwObjectCondition = m_dwObjectCondition ^ STACK_FULL;
-
- m_queuePos--;
- m_lpvProcessor = m_lppvQueue[m_queuePos];
- m_mutex.Unlock();
- return TRUE;
-}
-
-
-/**
- *
- * SetThreadType
- * specifies the type of threading that is to be performed.
- *
- * ThreadTypeEventDriven (default): an event must be physically sent
- * to the thread using the Event member
- * function.
- *
- * ThreadTypeIntervalDriven : an event occurs automatically every
- * dwIdle milli seconds.
- *
- **/
-void
-CThread::SetThreadType(ThreadType_t typ,
- DWORD dwIdle)
-{
-
- try
- {
- if( FromSameThread() )
- {
- throw "\n\tit is illegal for a thread to change its own type!\n";
- }
-
-
- m_mutex.Lock();
- m_dwIdle = dwIdle;
-
-
- if( m_type == typ ) {
- m_mutex.Unlock();
- return;
- }
- if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
- m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
- if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH )
- m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
- m_type = typ;
-
-
- m_mutex.Unlock();
- m_event.Set();
- }
- catch (char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::SetThreadType",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::SetThreadType(ThreadType_t typ):" << psz;
-#endif
-
- }
-}
-
-
-/**
- *
- * Stop
- * stop thread
- *
- **/
-BOOL
-CThread::Stop()
-{
- try
- {
- if( FromSameThread() )
- {
- throw "\n\tit is illegal for a thread to attempt to signal itself to stop!\n";
- }
-
- m_mutex.Lock();
- m_bRunning = FALSE;
- m_mutex.Unlock();
- m_event.Set();
-
- int ticks = (m_StopTimeout*1000)/100;
-
- for( int i=0; i<ticks; i++ )
- {
- Sleep(100);
-
- m_mutex.Lock();
- if( m_state == ThreadStateDown )
- {
- m_mutex.Unlock();
- return TRUE;
- }
- m_mutex.Unlock();
-
- }
- }
- catch (char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Stop",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::Stop():" << psz;
-#endif
-
- }
- return FALSE;
-}
-
-
-/**
- *
- * SetIdle
- * changes the threads idle interval
- *
- **/
-void
-CThread::SetIdle(DWORD dwIdle)
-{
- m_mutex.Lock();
- m_dwIdle = dwIdle;
- m_mutex.Unlock();
-}
-
-/**
- *
- * Start
- * start thread
- *
- **/
-BOOL
-CThread::Start()
-{
- try
- {
- if( FromSameThread() )
- {
- throw "\n\tit is illegal for a thread to attempt to start itself!\n";
- }
-
-
- m_mutex.Lock();
- if( m_bRunning )
- {
- m_mutex.Unlock();
- return TRUE;
- }
-
- m_mutex.Unlock();
-
-
- if( m_dwObjectCondition & THREAD_CREATION )
- m_dwObjectCondition = m_dwObjectCondition ^ THREAD_CREATION;
-
-#ifdef WINDOWS
- if( m_thread ) CloseHandle(m_thread);
-#ifdef USE_BEGIN_THREAD
- m_thread = (HANDLE )_beginthreadex(NULL,(unsigned int)m_stackSize,_THKERNEL,(LPVOID)this,0,&m_dwId);
-#else
- m_thread = CreateThread(NULL,m_stackSize ,_THKERNEL,(LPVOID)this,0,&m_dwId);
-#endif
- if( !m_thread )
- {
- perror("thread creation failed");
- m_dwObjectCondition |= THREAD_CREATION;
- m_state = ThreadStateFault;
- return FALSE;
- }
-#else
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
-
-#ifdef VMS
- if( m_stackSize == 0 )
- pthread_attr_setstacksize(&attr,PTHREAD_STACK_MIN*10);
-#endif
- if( m_stackSize != 0 )
- pthread_attr_setstacksize(&attr,m_stackSize);
-
- int error = pthread_create(&m_thread,&attr,_THKERNEL,(LPVOID)this);
-
- if( error != 0 )
- {
- m_dwObjectCondition |= THREAD_CREATION;
- m_state = ThreadStateFault;
-
-#if defined(HPUX) || defined(SUNOS) || defined(LINUX)
- switch(error)/* show the thread error */
- {
-
- case EINVAL:
- cerr << "error: attr in an invalid thread attributes object\n";
- break;
- case EAGAIN:
- cerr << "error: the necessary resources to create a thread are not\n";
- cerr << "available.\n";
- break;
- case EPERM:
- cerr << "error: the caller does not have the privileges to create\n";
- cerr << "the thread with the specified attr object.\n";
- break;
-#if defined(HPUX)
- case ENOSYS:
-
- cerr << "error: pthread_create not implemented!\n";
- if( __is_threadlib_linked()==0 )
- {
- cerr << "error: threaded library not being used, improper linkage \"-lpthread -lc\"!\n";
- }
- break;
-#endif
- default:
- cerr << "error: an unknown error was encountered attempting to create\n";
- cerr << "the requested thread.\n";
- break;
- }
-#else
- cerr << "error: could not create thread, pthread_create failed (" << error << ")!\n";
-#endif
- return FALSE;
- }
-#endif
- }
- catch (char *psz)
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Start",MB_ICONHAND);
-#else
- cerr << "Fatal exception CThread::Start():" << psz;
-#endif
- exit(-1);
- }
- return TRUE;
-}
-
-/**
- *
- * AtCapacity
- * returns TRUE if the threads queue is full, and the thread
- * is busy processing an event or the thread is not running
- *
- **/
-BOOL
-CThread::AtCapacity()
-{
- m_mutex.Lock();
- if( ((m_dwObjectCondition & STACK_OVERFLOW ||
- m_dwObjectCondition & STACK_FULL ) &&
- m_state == ThreadStateBusy) || !m_bRunning)
- {
- m_mutex.Unlock();
- return TRUE;
- }
- m_mutex.Unlock();
- return FALSE;
-}
-
-/**
- *
- * ThreadState
- * return the current state of the thread
- *
- **/
-ThreadState_t
-CThread::ThreadState()
-{
- ThreadState_t currentState;
- m_mutex.Lock();
- currentState = m_state;
- m_mutex.Unlock();
- return currentState;
-}
-
-/**
- *
- * ~CThread
- * destructor. Stop should be called prior to destruction to
- * allow for gracefull thread termination.
- *
- **/
-CThread::~CThread(void)
-{
- if( m_bRunning ) // gracefull termination
- {
- try
- {
- if( !Stop() )
- {
- throw "\n\tthread failed to stop in a timely manner!\n";
- }
- }
- catch( char *psz )
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Stop",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::Stop: " << psz;
-#endif
- }
- }
-#ifdef WINDOWS
- CloseHandle(m_thread);
-#endif
-
- delete [] m_lppvQueue;
-}
-
-
-/**
- *
- * PingThread
- * used to determine if a thread is running
- *
- **/
-BOOL
-CThread::PingThread(DWORD dwTimeout /* timeout in milli-seconds */
- )
-{
- DWORD dwTotal = 0;
-
- while(TRUE)
- {
- if( dwTotal > dwTimeout && dwTimeout > 0 )
- return FALSE;
- m_mutex.Lock();
- if( m_bRunning )
- {
- m_mutex.Unlock();
- return TRUE;
- }
- dwTotal += m_dwIdle;
- m_mutex.Unlock();
- Sleep(m_dwIdle);
- }
-
- return FALSE;
-}
-
-/**
- *
- * WaitTillExit
- * blocks caller until thread exits
- *
- **/
-void
-CThread::WaitTillExit()
-{
-
- /*
- *
- * prevent users from calling this function from within the same thread
- * of execution
- *
- */
- try
- {
- if( FromSameThread() )
- throw "\n\tthis function can not be called from within the same thread!\n";
-
-
-
-
- if( !m_bRunning ) return;
-
-
-#ifdef WINDOWS
- WaitForSingleObject(m_thread,INFINITE);
-#else
- LPVOID lpv;
-
- pthread_join(m_thread,&lpv);
-#endif
- }
- catch( char *psz )
- {
-#ifdef WINDOWS
- MessageBoxA(NULL,&psz[2],"Fatal exception CThread::WaitTillExit",MB_ICONHAND);
- exit(-1);
-#else
- cerr << "Fatal exception CThread::WaitTillExit: " << psz;
-#endif
-
- }
-}
-
-
-
-
diff --git a/jni/libzrtp/sources/common/Thread.h b/jni/libzrtp/sources/common/Thread.h
deleted file mode 100644
index ca77255..0000000
--- a/jni/libzrtp/sources/common/Thread.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//
-// Thread.h: header file
-//
-// Copyright (C) Walter E. Capers. All rights reserved
-//
-// This source is free to use as you like. If you make
-// any changes please keep me in the loop. Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-// To implement Win32 threading as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.24.07
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 10.24.07 11:49 am
-// Name: Walter E. Capers
-// Description: Added SetIdle function to allow the idle time to be altered
-// independent of the SetThreadType member function.
-// Date: 10.31.07
-// Name: Walter E. Capers
-// Description: Added support for beginthreadex
-// To use compile with -DUSE_BEGIN_THREAD
-//
-//
-
-#ifndef THREAD_CLASS
-#define THREAD_CLASS
-
-#ifndef WINDOWS
-#if defined(_WIN32) || defined(_WIN64)
-#define WINDOWS
-#endif
-#endif
-#ifdef __APPLE__
-#define VMS
-#endif
-
-#ifndef WINDOWS
-#include <stdio.h>
-#include <string.h>
-//#include <malloc.h>
-#include <memory.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-typedef unsigned char BOOL;
-#define TRUE 1
-#define FALSE 0
-typedef long DWORD;
-typedef void *LPVOID;
-#else
-#include "afx.h"
-/* #include <windows.h> */
-#include <stdio.h>
-#endif
-
-#if defined(AS400) || defined(OS400)
-typedef pthread_id_np_t ThreadId_t;
-#elif defined(VMS) || defined(__NetBSD__)
-typedef pthread_t ThreadId_t;
-#else
-#ifdef USE_BEGIN_THREAD
-typedef unsigned ThreadId_t;
-#else
-typedef DWORD ThreadId_t;
-#endif
-#endif
-
-#include <common/MutexClass.h>
-#include <common/EventClass.h>
-
-#define QUEUE_SIZE 100
-#define DEFAULT_STACK_SIZE 0
-#ifndef WINDOWS
-void Sleep( unsigned int mseconds);
-#endif
-
-#ifndef ASSERT
-#if defined(DEBUG) || defined(_DEBUG)
-#define ASSERT(test) if( !(test) ) { \
- fprintf(stderr,"\nASSERT(%s) FAILS, %s line %d\n",#test,__FILE__, __LINE__); exit(0);}
-#else
-#define ASSERT(test)
-#endif
-#endif
-
-
-typedef enum {
- ThreadStateBusy, // thread is currently handling a task
- ThreadStateWaiting, // thread is waiting for something to do
- ThreadStateDown, // thread is not running
- ThreadStateShuttingDown, // thread is in the process of shutting down
- ThreadStateFault // an error has occured and the thread could not
- // be launched
-} ThreadState_t;
-
-typedef enum {
- ThreadTypeHomogeneous,
- ThreadTypeSpecialized,
- ThreadTypeIntervalDriven,
- ThreadTypeNotDefined } ThreadType_t;
-
-
-typedef enum {
- TaskStatusNotSubmitted,
- TaskStatusWaitingOnQueue,
- TaskStatusBeingProcessed,
- TaskStatusCompleted } TaskStatus_t;
-
-class CTask
-{
-private:
- TaskStatus_t m_state;
- ThreadId_t m_dwThread;
-public:
- CMutexClass m_mutex;
-
- void SetTaskStatus(TaskStatus_t state)
- {
- m_mutex.Lock();
- m_state=state;
- m_mutex.Unlock();
- }
-
- void SetId(ThreadId_t *pid)
- {
- memcpy(&m_dwThread,pid,sizeof(ThreadId_t));
- }
-
- /**
- *
- * Wait
- * waits for upto timeoutSeconds for a task
- * to complete
- *
- **/
- BOOL Wait(int timeoutSeconds)
- {
- timeoutSeconds = timeoutSeconds * 1000;
- if( Status() != TaskStatusCompleted &&
- timeoutSeconds > 0 )
- {
- Sleep(100);
- timeoutSeconds = timeoutSeconds - 100;
- }
- if( Status() == TaskStatusCompleted ) return TRUE;
- return FALSE;
- }
-
- /**
- *
- * Status
- * returns current state of a task
- *
- **/
- TaskStatus_t Status()
- {
- TaskStatus_t state ;
-
- m_mutex.Lock();
- state = m_state;
- m_mutex.Unlock();
- return state;
- }
-
- void Thread(ThreadId_t *pId)
- {
- memcpy(pId,&m_dwThread,sizeof(ThreadId_t));
- }
-
- CTask(){m_state=TaskStatusNotSubmitted; memset(&m_dwThread,0,sizeof(ThreadId_t)); }
- ~CTask(){}
- virtual BOOL Task()=0;
-};
-
-
-class CThread
-#ifdef WINDOWS
- : public CObject // use CObject as a base class so object can be used in lists and
- // object arrays
-#endif
-{
-private:
- CEventClass m_event; // event controller
- int m_StopTimeout; // specifies a timeout value for stop
- // if a thread fails to stop within m_StopTimeout
- // seconds an exception is thrown
-
- BOOL m_bRunning; // set to TRUE if thread is running
-#ifdef WINDOWS
- HANDLE m_thread; // thread handle
-#else
- pthread_t m_thread; // thread handle
-#endif
- ThreadId_t m_dwId; // id of this thread
- LPVOID *m_lppvQueue; // task que
- unsigned int m_chQueue; // que depth
- unsigned int m_queuePos; // current que possition
- LPVOID m_lpvProcessor; // data which is currently being processed
- ThreadState_t m_state; // current state of thread see thread state data
- // structure.
- DWORD m_dwIdle; // used for Sleep periods
- ThreadType_t m_type;
- DWORD m_stackSize; // thread stack size
-#define NO_ERRORS 0
-#define MUTEX_CREATION 0x01
-#define EVENT_CREATION 0x02
-#define THREAD_CREATION 0x04
-#define UNKNOWN 0x08
-#define ILLEGAL_USE_OF_EVENT 0x10
-#define MEMORY_FAULT 0x20
-#define EVENT_AND_TYPE_DONT_MATCH 0x40
-#define STACK_OVERFLOW 0x80
-#define STACK_EMPTY 0x100
-#define STACK_FULL 0x200
-
- DWORD m_dwObjectCondition;
- BOOL Push(LPVOID lpv);
- BOOL Pop();
- BOOL Empty();
-public:
- /**
- *
- * user definable member functions
- *
- **/
- CMutexClass m_mutex; // mutex that protects threads internal data
-
- virtual BOOL OnTask(LPVOID lpvData); // called when an event occurs
- virtual BOOL OnTask(); // called when a time interval has elapsed
-
- CThread(void);
- ~CThread(void);
-#ifdef WINDOWS
-#ifdef USE_BEGIN_THREAD
- friend unsigned __stdcall _THKERNEL(LPVOID lpvData);
-#else
- friend DWORD WINAPI _THKERNEL( LPVOID lpvData );
-#endif
-#else
- friend LPVOID _THKERNEL(LPVOID lpvData);
-#endif
- BOOL FromSameThread();
- float PercentCapacity();
- void WaitTillExit();
- BOOL KernelProcess();
- BOOL Event(LPVOID lpvData=NULL);
- BOOL Event(CTask *pvTask);
- void SetOnStopTimeout(int seconds ) { m_StopTimeout = seconds; }
- BOOL SetQueueSize( unsigned int ch );
- BOOL Stop();
- BOOL Start();
- void GetId(ThreadId_t *pId) { memcpy(pId,&m_dwId,sizeof(ThreadId_t)); } // returns thread id
- ThreadState_t ThreadState();
- BOOL PingThread(DWORD dwTimeout=0);
- BOOL AtCapacity();
-#ifdef WINDOWS
- void SetPriority(DWORD dwPriority=THREAD_PRIORITY_NORMAL);
-#else
- void SetPriority(DWORD dwPriority=0);
-#endif
- DWORD GetErrorFlags() { return m_dwObjectCondition; } // returns state of object
- void SetThreadType(ThreadType_t typ=ThreadTypeNotDefined,DWORD dwIdle=100);
- void SetIdle(DWORD dwIdle=100);
- unsigned int GetEventsPending();
- static BOOL ThreadIdsEqual(ThreadId_t *p1,
- ThreadId_t *p2)
- {
-#if defined(AS400)||defined(OS400)
- return(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?TRUE:FALSE);
-#elif defined(VMS) || defined(__NetBSD__)
- return (( pthread_equal(*p1,*p2) )?TRUE:FALSE );
-#else
- return ((*p1 == *p2)?TRUE:FALSE);
-#endif
-
- }
-
- static ThreadId_t ThreadId()
- {
- ThreadId_t thisThreadsId ;
-#if defined(AS400) || defined(OS400)
- pthread_t thread;
-#endif
-
-#ifdef WINDOWS
- thisThreadsId = (ThreadId_t)GetCurrentThreadId();
-#else
-
-#if defined(AS400) || defined(OS400)
- thread = pthread_self();
- pthread_getunique_np(&thread,&thisThreadsId);
-#elif defined(ALPHA) || defined(DEC) || defined(VMS)
-#ifdef VMS
- thisThreadsId = pthread_self();
-#else
- thisThreadsId = pthread_getsequence_np(pthread_self());
-#endif
-#else
- thisThreadsId = pthread_self();
-#endif
-#endif
- return thisThreadsId;
- }
-
-
-};
-#endif
-
diff --git a/jni/libzrtp/sources/common/osSpecifics.c b/jni/libzrtp/sources/common/osSpecifics.c
deleted file mode 100644
index 3345363..0000000
--- a/jni/libzrtp/sources/common/osSpecifics.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include <stdint.h>
-#include <common/osSpecifics.h>
-
-
-#if defined(_WIN32) || defined(_WIN64)
-
-#else
-
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# include <WinSock2.h>
-# include <time.h>
-
-uint64_t zrtpGetTickCount()
-{
- // return GetTickCount64(); //works only on 64bit OS
- unsigned long long ret;
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- ret = ft.dwHighDateTime;
- ret <<= 32;
- ret |= ft.dwLowDateTime;
-
- return ret / 10; //return msec
-}
-#else
-# include <netinet/in.h>
-# include <sys/time.h>
-
-uint64_t zrtpGetTickCount()
-{
- struct timeval tv;
- gettimeofday(&tv, 0);
-
- return ((uint64_t)tv.tv_sec) * (uint64_t)1000 + ((uint64_t)tv.tv_usec) / (uint64_t)1000;
-}
-
-#endif
-
-uint32_t zrtpNtohl (uint32_t net)
-{
- return ntohl(net);
-}
-
-uint16_t zrtpNtohs (uint16_t net)
-{
- return ntohs(net);
-}
-
-uint32_t zrtpHtonl (uint32_t host)
-{
- return htonl(host);
-}
-uint16_t zrtpHtons (uint16_t host)
-{
- return htons(host);
-}
-
diff --git a/jni/libzrtp/sources/common/osSpecifics.h b/jni/libzrtp/sources/common/osSpecifics.h
deleted file mode 100644
index 5030688..0000000
--- a/jni/libzrtp/sources/common/osSpecifics.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _OSSPECIFICS_H_
-#define _OSSPECIFICS_H_
-
-/**
- * @file osSpecifics.h
- * @brief Some functions to adapt to OS and/or compiler specific handling
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- *
- * This modules contains some functions that are either specific for a particular
- * OS or use include files that are not common.
- *
- * This header file shall not #include system specific header files and shall also
- * not use specific #ifdef stuff. Refer to @c osSpecifics.c for the OS specific
- * #include, #ifdef and implementations.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef __EXPORT
- #if (defined _WIN32 || defined __CYGWIN__) && defined(_DLL)
- #define __EXPORT __declspec(dllimport)
- #define __LOCAL
- #elif __GNUC__ >= 4
- #define __EXPORT __attribute__ ((visibility("default")))
- #define __LOCAL __attribute__ ((visibility("hidden")))
- #else
- #define __EXPORT
- #define __LOCAL
- #endif
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-/**
- * Get surrent system time in milli-second.
- *
- * @return current time in ms.
- */
-extern uint64_t zrtpGetTickCount();
-
-/**
- * Convert a 32bit variable from network to host order.
- *
- * Replaces the macros found in @c inet.h or @c WinSock2.h. Use this function
- * to avoid different includes freamed with @c #idef in the sources. Including
- * @c WinSock2 will increase compile time and may lead to other subtle problems
- * because @c WinSock2 also includes @c windows.h.
- *
- * @param net 32bit variable in network byte order.
- *
- * @return 32bit variable in host byte order.
- */
-extern uint32_t zrtpNtohl (uint32_t net);
-
-/**
- * Convert a 16bit variable from network to host order.
- *
- * @param net 16bit variable in network byte order.
- *
- * @return 16bit variable in host byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint16_t zrtpNtohs (uint16_t net);
-
-/**
- * Convert a 32bit variable from host to network order.
- *
- * @param host 32bit variable in host byte order.
- *
- * @return 32bit variable in network byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint32_t zrtpHtonl (uint32_t host);
-
-/**
- * Convert a 16bit variable from host to network order.
- *
- * @param host 16bit variable in host byte order.
- *
- * @return 16bit variable in network byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint16_t zrtpHtons (uint16_t host);
-
-#if defined(__cplusplus)
-}
-#endif
-
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
deleted file mode 100644
index c19fa82..0000000
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2006-2013 Werner Dittmann
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-
-#include <cryptcommon/ZrtpRandom.h>
-#include <cryptcommon/aescpp.h>
-#include <common/Thread.h>
-#include <zrtp/crypto/sha2.h>
-
-static sha512_ctx mainCtx;
-
-static CMutexClass lockRandom;
-
-static bool initialized = false;
-
-/*
- * Random bits are produced as follows.
- * First stir new entropy into the random state (zrtp->rand_ctx).
- * Then make a copy of the random context and finalize it.
- * Use the digest to seed an AES-256 context and, if space remains, to
- * initialize a counter.
- * Then encrypt the counter with the AES-256 context, incrementing it
- * per block, until we have produced the desired quantity of data.
- */
-/*----------------------------------------------------------------------------*/
-int ZrtpRandom::getRandomData(uint8_t* buffer, uint32_t length) {
-
- AESencrypt aesCtx;
- sha512_ctx randCtx2;
- uint8_t md[SHA512_DIGEST_SIZE];
- uint8_t ctr[AES_BLOCK_SIZE];
- uint8_t rdata[AES_BLOCK_SIZE];
- uint32_t generated = length;
-
- /*
- * Add entropy from system state
- * We will include whatever happens to be in the buffer, it can't hurt
- */
- ZrtpRandom::addEntropy(buffer, length);
-
- lockRandom.Lock();
-
- /* Copy the mainCtx and finalize it into the md buffer */
- memcpy(&randCtx2, &mainCtx, sizeof(sha512_ctx));
- sha512_end(md, &randCtx2);
-
- lockRandom.Unlock();
-
- /* Key an AES context from this buffer */
- aesCtx.key256(md);
-
- /* Initialize counter, using excess from md if available */
- memset (ctr, 0, sizeof(ctr));
- if (SHA512_DIGEST_SIZE > (256/8)) {
- uint32_t ctrbytes = SHA512_DIGEST_SIZE - (256/8);
- if (ctrbytes > AES_BLOCK_SIZE)
- ctrbytes = AES_BLOCK_SIZE;
- memcpy(ctr + sizeof(ctr) - ctrbytes, md + (256/8), ctrbytes);
- }
-
- /* Encrypt counter, copy to destination buffer, increment counter */
- while (length) {
- uint8_t *ctrptr;
- uint32_t copied;
- aesCtx.encrypt(ctr, rdata);
- copied = (sizeof(rdata) < length) ? sizeof(rdata) : length;
- memcpy (buffer, rdata, copied);
- buffer += copied;
- length -= copied;
-
- /* Increment counter */
- ctrptr = ctr + sizeof(ctr) - 1;
- while (ctrptr >= ctr) {
- if ((*ctrptr-- += 1) != 0) {
- break;
- }
- }
- }
- memset(&randCtx2, 0, sizeof(randCtx2));
- memset(md, 0, sizeof(md));
- memset(&aesCtx, 0, sizeof(aesCtx));
- memset(ctr, 0, sizeof(ctr));
- memset(rdata, 0, sizeof(rdata));
-
- return generated;
-}
-
-
-int ZrtpRandom::addEntropy(const uint8_t *buffer, uint32_t length)
-{
-
- uint8_t newSeed[64];
- size_t len = getSystemSeed(newSeed, sizeof(newSeed));
-
- lockRandom.Lock();
- initialize();
-
- if (buffer && length) {
- sha512_hash(buffer, length, &mainCtx);
- }
- if (len > 0) {
- sha512_hash(newSeed, len, &mainCtx);
- length += len;
- }
- lockRandom.Unlock();
- return length;
-}
-
-
-void ZrtpRandom::initialize() {
- if (initialized)
- return;
-
- sha512_begin(&mainCtx);
- initialized = true;
-}
-
-/*
- * This works for Linux and similar systems. For other systems add
- * other functions (using #ifdef conditional compile) to get some
- * random data that we can use as seed for the internal PRNG below.
- */
-
-size_t ZrtpRandom::getSystemSeed(uint8_t *seed, size_t length)
-{
- size_t num = 0;
-
-#if !(defined(_WIN32) || defined(_WIN64))
- int rnd = open("/dev/urandom", O_RDONLY);
- if (rnd >= 0) {
- num = read(rnd, seed, length);
- close(rnd);
- }
- else
- return num;
-#endif
- return num;
-}
-
-int zrtp_AddEntropy(const uint8_t *buffer, uint32_t length) {
- return ZrtpRandom::addEntropy(buffer, length);
-}
-
-int zrtp_getRandomData(uint8_t *buffer, uint32_t length) {
- return ZrtpRandom::getRandomData(buffer, length);
-}
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
deleted file mode 100644
index d3eedf7..0000000
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTPRANDOM_H_
-#define _ZRTPRANDOM_H_
-
-/**
- * @file ZrtpCommon.h
- * @brief ZRTP standalone random number generator
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- */
-
-#include <string.h>
-#if !(defined(_WIN32) || defined(_WIN64))
-#include <unistd.h>
-#endif
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-class ZrtpRandom {
-public:
- /**
- * @brief This method adds entropy to the PRNG.
- *
- * An application may seed some entropy data to the PRNG. If the @c buffer is
- * @c NULL or the @c length is zero then the method adds at least some system
- * entropy.
- *
- * @param buffer some entropy data to add
- *
- * @param length length of entropy data in bytes
- *
- * @return on success: number of entropy bytes added, on failure: -1. Number of
- * bytes added may be bigger then @c length because of added system
- * entropy.
- */
- static int addEntropy(const uint8_t *buffer, uint32_t length);
-
- /**
- * @brief Get some random data.
- *
- * @param buffer that will contain the random data
- *
- * @param length how many bytes of random data to generate
- *
- * @return the number of generated random data bytes
- */
- static int getRandomData(uint8_t *buffer, uint32_t length);
-
-private:
- static void initialize();
- static size_t getSystemSeed(uint8_t *seed, size_t length);
-
-};
-#endif
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-int zrtp_AddEntropy(const uint8_t *buffer, uint32_t length);
-
-int zrtp_getRandomData(uint8_t *buffer, uint32_t length);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZRTPRANDOM */
\ No newline at end of file
diff --git a/jni/libzrtp/sources/cryptcommon/aes.h b/jni/libzrtp/sources/cryptcommon/aes.h
deleted file mode 100644
index 40927fb..0000000
--- a/jni/libzrtp/sources/cryptcommon/aes.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the definitions required to use AES in C. See aesopt.h
- for optimisation details.
-*/
-
-#ifndef _AES_H
-#define _AES_H
-
-#include <stdlib.h>
-
-/* This include is used to find 8 & 32 bit unsigned integer types */
-#include "brg_types.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define AES_128 /* if a fast 128 bit key scheduler is needed */
-#define AES_192 /* if a fast 192 bit key scheduler is needed */
-#define AES_256 /* if a fast 256 bit key scheduler is needed */
-#define AES_VAR /* if variable key size scheduler is needed */
-#define AES_MODES /* if support is needed for modes */
-
-/* The following must also be set in assembler files if being used */
-
-#define AES_ENCRYPT /* if support for encryption is needed */
-#define AES_DECRYPT /* if support for decryption is needed */
-#define AES_REV_DKS /* define to reverse decryption key schedule */
-
-#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
-#define N_COLS 4 /* the number of columns in the state */
-
-/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
-/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
-/* or 44, 52 or 60 32-bit words. */
-
-#if defined( AES_VAR ) || defined( AES_256 )
-#define KS_LENGTH 60
-#elif defined( AES_192 )
-#define KS_LENGTH 52
-#else
-#define KS_LENGTH 44
-#endif
-
-#define AES_RETURN INT_RETURN
-
-/* the character array 'inf' in the following structures is used */
-/* to hold AES context information. This AES code uses cx->inf.b[0] */
-/* to hold the number of rounds multiplied by 16. The other three */
-/* elements can be used by code that implements additional modes */
-
-typedef union
-{ uint_32t l;
- uint_8t b[4];
-} aes_inf;
-
-typedef struct
-{ uint_32t ks[KS_LENGTH];
- aes_inf inf;
-} aes_encrypt_ctx;
-
-typedef struct
-{ uint_32t ks[KS_LENGTH];
- aes_inf inf;
-} aes_decrypt_ctx;
-
-/* This routine must be called before first use if non-static */
-/* tables are being used */
-
-AES_RETURN aes_init(void);
-
-/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
-/* those in the range 128 <= key_len <= 256 are given in bits */
-
-#if defined( AES_ENCRYPT )
-
-#if defined( AES_128 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_192 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_256 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_VAR )
-AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
-#endif
-
-AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
-
-#endif
-
-#if defined( AES_DECRYPT )
-
-#if defined( AES_128 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_192 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_256 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_VAR )
-AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
-#endif
-
-AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
-
-#endif
-
-#if defined( AES_MODES )
-
-/* Multiple calls to the following subroutines for multiple block */
-/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
-/* long messages incremantally provided that the context AND the iv */
-/* are preserved between all such calls. For the ECB and CBC modes */
-/* each individual call within a series of incremental calls must */
-/* process only full blocks (i.e. len must be a multiple of 16) but */
-/* the CFB, OFB and CTR mode calls can handle multiple incremental */
-/* calls of any length. Each mode is reset when a new AES key is */
-/* set but ECB and CBC operations can be reset without setting a */
-/* new key by setting a new IV value. To reset CFB, OFB and CTR */
-/* without setting the key, aes_mode_reset() must be called and the */
-/* IV must be set. NOTE: All these calls update the IV on exit so */
-/* this has to be reset if a new operation with the same IV as the */
-/* previous one is required (or decryption follows encryption with */
-/* the same IV array). */
-
-AES_RETURN aes_test_alignment_detection(unsigned int n);
-
-AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, const aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, const aes_decrypt_ctx cx[1]);
-
-AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
-
-AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-#define aes_ofb_encrypt aes_ofb_crypt
-#define aes_ofb_decrypt aes_ofb_crypt
-
-AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-typedef void cbuf_inc(unsigned char *cbuf);
-
-#define aes_ctr_encrypt aes_ctr_crypt
-#define aes_ctr_decrypt aes_ctr_crypt
-
-AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aes_modes.c b/jni/libzrtp/sources/cryptcommon/aes_modes.c
deleted file mode 100644
index 2ffa783..0000000
--- a/jni/libzrtp/sources/cryptcommon/aes_modes.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- These subroutines implement multiple block AES modes for ECB, CBC, CFB,
- OFB and CTR encryption, The code provides support for the VIA Advanced
- Cryptography Engine (ACE).
-
- NOTE: In the following subroutines, the AES contexts (ctx) must be
- 16 byte aligned if VIA ACE is being used
-*/
-
-#include <string.h>
-#include <assert.h>
-
-#include "aesopt.h"
-
-#if defined( AES_MODES )
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#define BFR_BLOCKS 8
-
-/* These values are used to detect long word alignment in order to */
-/* speed up some buffer operations. This facility may not work on */
-/* some machines so this define can be commented out if necessary */
-
-#define FAST_BUFFER_OPERATIONS
-
-#define lp32(x) ((uint_32t*)(x))
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-#include "aes_via_ace.h"
-
-#pragma pack(16)
-
-aligned_array(unsigned long, enc_gen_table, 12, 16) = NEH_ENC_GEN_DATA;
-aligned_array(unsigned long, enc_load_table, 12, 16) = NEH_ENC_LOAD_DATA;
-aligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA;
-aligned_array(unsigned long, dec_gen_table, 12, 16) = NEH_DEC_GEN_DATA;
-aligned_array(unsigned long, dec_load_table, 12, 16) = NEH_DEC_LOAD_DATA;
-aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;
-
-/* NOTE: These control word macros must only be used after */
-/* a key has been set up because they depend on key size */
-/* See the VIA ACE documentation for key type information */
-/* and aes_via_ace.h for non-default NEH_KEY_TYPE values */
-
-#ifndef NEH_KEY_TYPE
-# define NEH_KEY_TYPE NEH_HYBRID
-#endif
-
-#if NEH_KEY_TYPE == NEH_LOAD
-#define kd_adr(c) ((uint_8t*)(c)->ks)
-#elif NEH_KEY_TYPE == NEH_GENERATE
-#define kd_adr(c) ((uint_8t*)(c)->ks + (c)->inf.b[0])
-#elif NEH_KEY_TYPE == NEH_HYBRID
-#define kd_adr(c) ((uint_8t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0))
-#else
-#error no key type defined for VIA ACE
-#endif
-
-#else
-
-#define aligned_array(type, name, no, stride) type name[no]
-#define aligned_auto(type, name, no, stride) type name[no]
-
-#endif
-
-#if defined( _MSC_VER ) && _MSC_VER > 1200
-
-#define via_cwd(cwd, ty, dir, len) \
- unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4))
-
-#else
-
-#define via_cwd(cwd, ty, dir, len) \
- aligned_auto(unsigned long, cwd, 4, 16); \
- cwd[1] = cwd[2] = cwd[3] = 0; \
- cwd[0] = neh_##dir##_##ty##_key(len)
-
-#endif
-
-/* test the code for detecting and setting pointer alignment */
-
-AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */
-{ uint_8t p[16];
- uint_32t i, count_eq = 0, count_neq = 0;
-
- if(n < 4 || n > 16)
- return EXIT_FAILURE;
-
- for(i = 0; i < n; ++i)
- {
- uint_8t *qf = ALIGN_FLOOR(p + i, n),
- *qh = ALIGN_CEIL(p + i, n);
-
- if(qh == qf)
- ++count_eq;
- else if(qh == qf + n)
- ++count_neq;
- else
- return EXIT_FAILURE;
- }
- return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
-AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])
-{
- ctx->inf.b[2] = 0;
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, const aes_encrypt_ctx ctx[1])
-{ int nb = len >> 4;
-
- if(len & (AES_BLOCK_SIZE - 1))
- return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { uint_8t *ksp = (uint_8t*)(ctx->ks);
- via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
- {
- via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
- }
- else
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_ecb_op5(ksp, cwd, ip, op, m);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- nb -= m;
- }
- }
-
- return EXIT_SUCCESS;
- }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
- while(nb--)
- {
- if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
-#endif
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, const aes_decrypt_ctx ctx[1])
-{ int nb = len >> 4;
-
- if(len & (AES_BLOCK_SIZE - 1))
- return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { uint_8t *ksp = kd_adr(ctx);
- via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
- {
- via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
- }
- else
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_ecb_op5(ksp, cwd, ip, op, m);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- nb -= m;
- }
- }
-
- return EXIT_SUCCESS;
- }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
- while(nb--)
- {
- if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
-#endif
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, const aes_encrypt_ctx ctx[1])
-{ int nb = len >> 4;
-
- if(len & (AES_BLOCK_SIZE - 1))
- return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
- aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
- via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
- {
- ivp = liv;
- memcpy(liv, iv, AES_BLOCK_SIZE);
- }
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))
- {
- via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
- }
- else
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_cbc_op7(ksp, cwd, ip, op, m, ivp, ivp);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- nb -= m;
- }
- }
-
- if(iv != ivp)
- memcpy(iv, ivp, AES_BLOCK_SIZE);
-
- return EXIT_SUCCESS;
- }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
- while(nb--)
- {
- lp32(iv)[0] ^= lp32(ibuf)[0];
- lp32(iv)[1] ^= lp32(ibuf)[1];
- lp32(iv)[2] ^= lp32(ibuf)[2];
- lp32(iv)[3] ^= lp32(ibuf)[3];
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- memcpy(obuf, iv, AES_BLOCK_SIZE);
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
- else
-# endif
- while(nb--)
- {
- iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1];
- iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3];
- iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5];
- iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7];
- iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9];
- iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11];
- iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];
- iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- memcpy(obuf, iv, AES_BLOCK_SIZE);
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
-#endif
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])
-{ unsigned char tmp[AES_BLOCK_SIZE];
- int nb = len >> 4;
-
- if(len & (AES_BLOCK_SIZE - 1))
- return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { uint_8t *ksp = kd_adr(ctx), *ivp = iv;
- aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
- via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
- {
- ivp = liv;
- memcpy(liv, iv, AES_BLOCK_SIZE);
- }
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))
- {
- via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp);
- }
- else
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_cbc_op6(ksp, cwd, ip, op, m, ivp);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- nb -= m;
- }
- }
-
- if(iv != ivp)
- memcpy(iv, ivp, AES_BLOCK_SIZE);
-
- return EXIT_SUCCESS;
- }
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
- while(nb--)
- {
- memcpy(tmp, ibuf, AES_BLOCK_SIZE);
- if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- lp32(obuf)[0] ^= lp32(iv)[0];
- lp32(obuf)[1] ^= lp32(iv)[1];
- lp32(obuf)[2] ^= lp32(iv)[2];
- lp32(obuf)[3] ^= lp32(iv)[3];
- memcpy(iv, tmp, AES_BLOCK_SIZE);
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
- else
-# endif
- while(nb--)
- {
- memcpy(tmp, ibuf, AES_BLOCK_SIZE);
- if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];
- obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];
- obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];
- obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7];
- obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9];
- obuf[10] ^= iv[10]; obuf[11] ^= iv[11];
- obuf[12] ^= iv[12]; obuf[13] ^= iv[13];
- obuf[14] ^= iv[14]; obuf[15] ^= iv[15];
- memcpy(iv, tmp, AES_BLOCK_SIZE);
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
-#endif
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
- if(b_pos) /* complete any partial block */
- {
- while(b_pos < AES_BLOCK_SIZE && cnt < len)
- {
- *obuf++ = (iv[b_pos++] ^= *ibuf++);
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
- {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { int m;
- uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
- aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
- via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
- {
- ivp = liv;
- memcpy(liv, iv, AES_BLOCK_SIZE);
- }
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
- {
- via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
- ibuf += nb * AES_BLOCK_SIZE;
- obuf += nb * AES_BLOCK_SIZE;
- cnt += nb * AES_BLOCK_SIZE;
- }
- else /* input, output or both are unaligned */
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- cnt += m * AES_BLOCK_SIZE;
- }
- }
-
- if(ivp != iv)
- memcpy(iv, ivp, AES_BLOCK_SIZE);
- }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
- while(cnt + AES_BLOCK_SIZE <= len)
- {
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0];
- lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1];
- lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2];
- lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3];
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
- else
-# endif
- while(cnt + AES_BLOCK_SIZE <= len)
- {
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1];
- obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3];
- obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5];
- obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7];
- obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9];
- obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11];
- obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13];
- obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15];
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
-#endif
- }
-
- while(cnt < len)
- {
- if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- while(cnt < len && b_pos < AES_BLOCK_SIZE)
- {
- *obuf++ = (iv[b_pos++] ^= *ibuf++);
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- ctx->inf.b[2] = (uint_8t)b_pos;
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
- if(b_pos) /* complete any partial block */
- { uint_8t t;
-
- while(b_pos < AES_BLOCK_SIZE && cnt < len)
- {
- t = *ibuf++;
- *obuf++ = t ^ iv[b_pos];
- iv[b_pos++] = t;
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
- {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { int m;
- uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
- aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
- via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
- {
- ivp = liv;
- memcpy(liv, iv, AES_BLOCK_SIZE);
- }
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
- {
- via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp);
- ibuf += nb * AES_BLOCK_SIZE;
- obuf += nb * AES_BLOCK_SIZE;
- cnt += nb * AES_BLOCK_SIZE;
- }
- else /* input, output or both are unaligned */
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf) /* input buffer is not aligned */
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_cfb_op6(ksp, cwd, ip, op, m, ivp);
-
- if(op != obuf) /* output buffer is not aligned */
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- cnt += m * AES_BLOCK_SIZE;
- }
- }
-
- if(ivp != iv)
- memcpy(iv, ivp, AES_BLOCK_SIZE);
- }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 ))
- while(cnt + AES_BLOCK_SIZE <= len)
- { uint_32t t;
-
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t;
- t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t;
- t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t;
- t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
- else
-# endif
- while(cnt + AES_BLOCK_SIZE <= len)
- { uint_8t t;
-
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t;
- t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t;
- t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t;
- t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t;
- t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t;
- t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t;
- t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t;
- t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t;
- t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t;
- t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t;
- t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t;
- t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t;
- t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t;
- t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t;
- t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t;
- t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
-#endif
- }
-
- while(cnt < len)
- { uint_8t t;
-
- if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- while(cnt < len && b_pos < AES_BLOCK_SIZE)
- {
- t = *ibuf++;
- *obuf++ = t ^ iv[b_pos];
- iv[b_pos++] = t;
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- ctx->inf.b[2] = (uint_8t)b_pos;
- return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
- if(b_pos) /* complete any partial block */
- {
- while(b_pos < AES_BLOCK_SIZE && cnt < len)
- {
- *obuf++ = iv[b_pos++] ^ *ibuf++;
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */
- {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
- if(ctx->inf.b[1] == 0xff)
- { int m;
- uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
- aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
- via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
- if(ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-
- if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */
- {
- ivp = liv;
- memcpy(liv, iv, AES_BLOCK_SIZE);
- }
-
- if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
- {
- via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp);
- ibuf += nb * AES_BLOCK_SIZE;
- obuf += nb * AES_BLOCK_SIZE;
- cnt += nb * AES_BLOCK_SIZE;
- }
- else /* input, output or both are unaligned */
- { aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
- uint_8t *ip, *op;
-
- while(nb)
- {
- m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
- ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
- op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
- if(ip != ibuf)
- memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
- via_ofb_op6(ksp, cwd, ip, op, m, ivp);
-
- if(op != obuf)
- memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
- ibuf += m * AES_BLOCK_SIZE;
- obuf += m * AES_BLOCK_SIZE;
- cnt += m * AES_BLOCK_SIZE;
- }
- }
-
- if(ivp != iv)
- memcpy(iv, ivp, AES_BLOCK_SIZE);
- }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
- while(cnt + AES_BLOCK_SIZE <= len)
- {
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0];
- lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1];
- lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2];
- lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3];
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
- else
-# endif
- while(cnt + AES_BLOCK_SIZE <= len)
- {
- assert(b_pos == 0);
- if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
- obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1];
- obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3];
- obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5];
- obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7];
- obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9];
- obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11];
- obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13];
- obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15];
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- cnt += AES_BLOCK_SIZE;
- }
-#endif
- }
-
- while(cnt < len)
- {
- if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- while(cnt < len && b_pos < AES_BLOCK_SIZE)
- {
- *obuf++ = iv[b_pos++] ^ *ibuf++;
- cnt++;
- }
-
- b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
- }
-
- ctx->inf.b[2] = (uint_8t)b_pos;
- return EXIT_SUCCESS;
-}
-
-#define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE)
-
-AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
- int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1])
-{ unsigned char *ip;
- int i, blen, b_pos = (int)(ctx->inf.b[2]);
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
- aligned_auto(uint_8t, buf, BFR_LENGTH, 16);
- if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 ))
- return EXIT_FAILURE;
-#else
- uint_8t buf[BFR_LENGTH];
-#endif
-
- if(b_pos)
- {
- memcpy(buf, cbuf, AES_BLOCK_SIZE);
- if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- while(b_pos < AES_BLOCK_SIZE && len)
- {
- *obuf++ = *ibuf++ ^ buf[b_pos++];
- --len;
- }
-
- if(len)
- ctr_inc(cbuf), b_pos = 0;
- }
-
- while(len)
- {
- blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
-
- for(i = 0, ip = buf; i < (blen >> 4); ++i)
- {
- memcpy(ip, cbuf, AES_BLOCK_SIZE);
- ctr_inc(cbuf);
- ip += AES_BLOCK_SIZE;
- }
-
- if(blen & (AES_BLOCK_SIZE - 1))
- memcpy(ip, cbuf, AES_BLOCK_SIZE), i++;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
- if(ctx->inf.b[1] == 0xff)
- {
- via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
- via_ecb_op5((ctx->ks), cwd, buf, buf, i);
- }
- else
-#endif
- if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- i = 0; ip = buf;
-# ifdef FAST_BUFFER_OPERATIONS
- if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 ))
- while(i + AES_BLOCK_SIZE <= blen)
- {
- lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0];
- lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1];
- lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2];
- lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3];
- i += AES_BLOCK_SIZE;
- ip += AES_BLOCK_SIZE;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
- else
-#endif
- while(i + AES_BLOCK_SIZE <= blen)
- {
- obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1];
- obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3];
- obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5];
- obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7];
- obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9];
- obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11];
- obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13];
- obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15];
- i += AES_BLOCK_SIZE;
- ip += AES_BLOCK_SIZE;
- ibuf += AES_BLOCK_SIZE;
- obuf += AES_BLOCK_SIZE;
- }
-
- while(i++ < blen)
- *obuf++ = *ibuf++ ^ ip[b_pos++];
- }
-
- ctx->inf.b[2] = (uint_8t)b_pos;
- return EXIT_SUCCESS;
-}
-
-#if defined(__cplusplus)
-}
-#endif
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aescpp.h b/jni/libzrtp/sources/cryptcommon/aescpp.h
deleted file mode 100644
index 9e2e24c..0000000
--- a/jni/libzrtp/sources/cryptcommon/aescpp.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the definitions required to use AES (Rijndael) in C++.
-*/
-
-#ifndef _AESCPP_H
-#define _AESCPP_H
-
-#include "aes.h"
-
-#if defined( AES_ENCRYPT )
-
-class AESencrypt
-{
-public:
- aes_encrypt_ctx cx[1];
- AESencrypt(void) { aes_init(); };
-#if defined(AES_128)
- AESencrypt(const unsigned char key[])
- { aes_encrypt_key128(key, cx); }
- AES_RETURN key128(const unsigned char key[])
- { return aes_encrypt_key128(key, cx); }
-#endif
-#if defined(AES_192)
- AES_RETURN key192(const unsigned char key[])
- { return aes_encrypt_key192(key, cx); }
-#endif
-#if defined(AES_256)
- AES_RETURN key256(const unsigned char key[])
- { return aes_encrypt_key256(key, cx); }
-#endif
-#if defined(AES_VAR)
- AES_RETURN key(const unsigned char key[], int key_len)
- { return aes_encrypt_key(key, key_len, cx); }
-#endif
- AES_RETURN encrypt(const unsigned char in[], unsigned char out[]) const
- { return aes_encrypt(in, out, cx); }
-#ifndef AES_MODES
- AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const
- { while(nb--)
- { aes_encrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }
- }
-#endif
-#ifdef AES_MODES
- AES_RETURN mode_reset(void) { return aes_mode_reset(cx); }
-
- AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const
- { return aes_ecb_encrypt(in, out, nb, cx); }
-
- AES_RETURN cbc_encrypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[]) const
- { return aes_cbc_encrypt(in, out, nb, iv, cx); }
-
- AES_RETURN cfb_encrypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[])
- { return aes_cfb_encrypt(in, out, nb, iv, cx); }
-
- AES_RETURN cfb_decrypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[])
- { return aes_cfb_decrypt(in, out, nb, iv, cx); }
-
- AES_RETURN ofb_crypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[])
- { return aes_ofb_crypt(in, out, nb, iv, cx); }
-
- typedef void ctr_fn(unsigned char ctr[]);
-
- AES_RETURN ctr_crypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[], ctr_fn cf)
- { return aes_ctr_crypt(in, out, nb, iv, cf, cx); }
-
-#endif
-
-};
-
-#endif
-
-#if defined( AES_DECRYPT )
-
-class AESdecrypt
-{
-public:
- aes_decrypt_ctx cx[1];
- AESdecrypt(void) { aes_init(); };
-#if defined(AES_128)
- AESdecrypt(const unsigned char key[])
- { aes_decrypt_key128(key, cx); }
- AES_RETURN key128(const unsigned char key[])
- { return aes_decrypt_key128(key, cx); }
-#endif
-#if defined(AES_192)
- AES_RETURN key192(const unsigned char key[])
- { return aes_decrypt_key192(key, cx); }
-#endif
-#if defined(AES_256)
- AES_RETURN key256(const unsigned char key[])
- { return aes_decrypt_key256(key, cx); }
-#endif
-#if defined(AES_VAR)
- AES_RETURN key(const unsigned char key[], int key_len)
- { return aes_decrypt_key(key, key_len, cx); }
-#endif
- AES_RETURN decrypt(const unsigned char in[], unsigned char out[]) const
- { return aes_decrypt(in, out, cx); }
-#ifndef AES_MODES
- AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const
- { while(nb--)
- { aes_decrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }
- }
-#endif
-#ifdef AES_MODES
-
- AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const
- { return aes_ecb_decrypt(in, out, nb, cx); }
-
- AES_RETURN cbc_decrypt(const unsigned char in[], unsigned char out[], int nb,
- unsigned char iv[]) const
- { return aes_cbc_decrypt(in, out, nb, iv, cx); }
-#endif
-};
-
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aescrypt.c b/jni/libzrtp/sources/cryptcommon/aescrypt.c
deleted file mode 100644
index 6095f41..0000000
--- a/jni/libzrtp/sources/cryptcommon/aescrypt.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#include "aesopt.h"
-#include "aestab.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
-#define so(y,x,c) word_out(y, c, s(x,c))
-
-#if defined(ARRAYS)
-#define locals(y,x) x[4],y[4]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-#endif
-
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
- Pentium optimiation with small code but this is poor for decryption
- so we need to control this with the following VC++ pragmas
-*/
-
-#if defined( _MSC_VER ) && !defined( _WIN64 )
-#pragma optimize( "s", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
- macros give the input state variables which are needed in its
- computation for each row (r) of the state. All the alternative
- macros give the same end values but expand into different ways
- of calculating these values. In particular the complex macro
- used for dynamically variable block sizes is designed to expand
- to a compile time constant whenever possible but will expand to
- conditional clauses on some branches (I am grateful to Frank
- Yellin for this construction)
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
-
-#if defined(FT4_SET)
-#undef dec_fmvars
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
-#elif defined(FT1_SET)
-#undef dec_fmvars
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
-#else
-#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
-#else
-#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
-#endif
-
-AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
-{ uint_32t locals(b0, b1);
- const uint_32t *kp;
-#if defined( dec_fmvars )
- dec_fmvars; /* declare variables for fwd_mcol() if needed */
-#endif
-
- if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
- return EXIT_FAILURE;
-
- kp = cx->ks;
- state_in(b0, in, kp);
-
-#if (ENC_UNROLL == FULL)
-
- switch(cx->inf.b[0])
- {
- case 14 * 16:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- kp += 2 * N_COLS;
- case 12 * 16:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- kp += 2 * N_COLS;
- case 10 * 16:
- round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
- round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
- round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
- round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
- }
-
-#else
-
-#if (ENC_UNROLL == PARTIAL)
- { uint_32t rnd;
- for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
- {
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
- kp += N_COLS;
- round(fwd_rnd, b0, b1, kp);
- }
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
-#else
- { uint_32t rnd;
- for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
- {
- kp += N_COLS;
- round(fwd_rnd, b1, b0, kp);
- l_copy(b0, b1);
- }
-#endif
- kp += N_COLS;
- round(fwd_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out, b0);
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if ( FUNCS_IN_C & DECRYPTION_IN_C)
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
- Pentium optimiation with small code but this is poor for decryption
- so we need to control this with the following VC++ pragmas
-*/
-
-#if defined( _MSC_VER ) && !defined( _WIN64 )
-#pragma optimize( "t", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
- macros give the input state variables which are needed in its
- computation for each row (r) of the state. All the alternative
- macros give the same end values but expand into different ways
- of calculating these values. In particular the complex macro
- used for dynamically variable block sizes is designed to expand
- to a compile time constant whenever possible but will expand to
- conditional clauses on some branches (I am grateful to Frank
- Yellin for this construction)
-*/
-
-#define inv_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
-
-#if defined(IT4_SET)
-#undef dec_imvars
-#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
-#elif defined(IT1_SET)
-#undef dec_imvars
-#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
-#else
-#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
-#else
-#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
-#endif
-
-/* This code can work with the decryption key schedule in the */
-/* order that is used for encrytpion (where the 1st decryption */
-/* round key is at the high end ot the schedule) or with a key */
-/* schedule that has been reversed to put the 1st decryption */
-/* round key at the low end of the schedule in memory (when */
-/* AES_REV_DKS is defined) */
-
-#ifdef AES_REV_DKS
-#define key_ofs 0
-#define rnd_key(n) (kp + n * N_COLS)
-#else
-#define key_ofs 1
-#define rnd_key(n) (kp - n * N_COLS)
-#endif
-
-AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
-{ uint_32t locals(b0, b1);
-#if defined( dec_imvars )
- dec_imvars; /* declare variables for inv_mcol() if needed */
-#endif
- const uint_32t *kp;
-
- if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
- return EXIT_FAILURE;
-
- kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
- state_in(b0, in, kp);
-
-#if (DEC_UNROLL == FULL)
-
- kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
- switch(cx->inf.b[0])
- {
- case 14 * 16:
- round(inv_rnd, b1, b0, rnd_key(-13));
- round(inv_rnd, b0, b1, rnd_key(-12));
- case 12 * 16:
- round(inv_rnd, b1, b0, rnd_key(-11));
- round(inv_rnd, b0, b1, rnd_key(-10));
- case 10 * 16:
- round(inv_rnd, b1, b0, rnd_key(-9));
- round(inv_rnd, b0, b1, rnd_key(-8));
- round(inv_rnd, b1, b0, rnd_key(-7));
- round(inv_rnd, b0, b1, rnd_key(-6));
- round(inv_rnd, b1, b0, rnd_key(-5));
- round(inv_rnd, b0, b1, rnd_key(-4));
- round(inv_rnd, b1, b0, rnd_key(-3));
- round(inv_rnd, b0, b1, rnd_key(-2));
- round(inv_rnd, b1, b0, rnd_key(-1));
- round(inv_lrnd, b0, b1, rnd_key( 0));
- }
-
-#else
-
-#if (DEC_UNROLL == PARTIAL)
- { uint_32t rnd;
- for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
- {
- kp = rnd_key(1);
- round(inv_rnd, b1, b0, kp);
- kp = rnd_key(1);
- round(inv_rnd, b0, b1, kp);
- }
- kp = rnd_key(1);
- round(inv_rnd, b1, b0, kp);
-#else
- { uint_32t rnd;
- for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
- {
- kp = rnd_key(1);
- round(inv_rnd, b1, b0, kp);
- l_copy(b0, b1);
- }
-#endif
- kp = rnd_key(1);
- round(inv_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out, b0);
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aeskey.c b/jni/libzrtp/sources/cryptcommon/aeskey.c
deleted file mode 100644
index 10d3324..0000000
--- a/jni/libzrtp/sources/cryptcommon/aeskey.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#include "aesopt.h"
-#include "aestab.h"
-
-/*
-#ifdef USE_VIA_ACE_IF_PRESENT
-# include "aes_via_ace.h"
-#endif
-*/
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
- length can be specified in bytes, with legal values of 16, 24
- and 32, or in bits, with legal values of 128, 192 and 256. These
- values correspond with Nk values of 4, 6 and 8 respectively.
-
- The following macros implement a single cycle in the key
- schedule generation process. The number of cycles needed
- for each cx->n_col and nk value is:
-
- nk = 4 5 6 7 8
- ------------------------------
- cx->n_col = 4 10 9 8 7 7
- cx->n_col = 5 14 11 10 9 9
- cx->n_col = 6 19 15 12 11 11
- cx->n_col = 7 21 19 16 13 14
- cx->n_col = 8 29 23 19 17 14
-*/
-
-#if defined( REDUCE_CODE_SIZE )
-# define ls_box ls_sub
- uint_32t ls_sub(const uint_32t t, const uint_32t n);
-# define inv_mcol im_sub
- uint_32t im_sub(const uint_32t x);
-# ifdef ENC_KS_UNROLL
-# undef ENC_KS_UNROLL
-# endif
-# ifdef DEC_KS_UNROLL
-# undef DEC_KS_UNROLL
-# endif
-#endif
-
-#if (FUNCS_IN_C & ENC_KEYING_IN_C)
-
-#if defined(AES_128) || defined( AES_VAR )
-
-#define ke4(k,i) \
-{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
- k[4*(i)+5] = ss[1] ^= ss[0]; \
- k[4*(i)+6] = ss[2] ^= ss[1]; \
- k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-
-AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
-{ uint_32t ss[4];
-
- cx->ks[0] = ss[0] = word_in(key, 0);
- cx->ks[1] = ss[1] = word_in(key, 1);
- cx->ks[2] = ss[2] = word_in(key, 2);
- cx->ks[3] = ss[3] = word_in(key, 3);
-
-#ifdef ENC_KS_UNROLL
- ke4(cx->ks, 0); ke4(cx->ks, 1);
- ke4(cx->ks, 2); ke4(cx->ks, 3);
- ke4(cx->ks, 4); ke4(cx->ks, 5);
- ke4(cx->ks, 6); ke4(cx->ks, 7);
- ke4(cx->ks, 8);
-#else
- { uint_32t i;
- for(i = 0; i < 9; ++i)
- ke4(cx->ks, i);
- }
-#endif
- ke4(cx->ks, 9);
- cx->inf.l = 0;
- cx->inf.b[0] = 10 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_192) || defined( AES_VAR )
-
-#define kef6(k,i) \
-{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
- k[6*(i)+ 7] = ss[1] ^= ss[0]; \
- k[6*(i)+ 8] = ss[2] ^= ss[1]; \
- k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-}
-
-#define ke6(k,i) \
-{ kef6(k,i); \
- k[6*(i)+10] = ss[4] ^= ss[3]; \
- k[6*(i)+11] = ss[5] ^= ss[4]; \
-}
-
-AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
-{ uint_32t ss[6];
-
- cx->ks[0] = ss[0] = word_in(key, 0);
- cx->ks[1] = ss[1] = word_in(key, 1);
- cx->ks[2] = ss[2] = word_in(key, 2);
- cx->ks[3] = ss[3] = word_in(key, 3);
- cx->ks[4] = ss[4] = word_in(key, 4);
- cx->ks[5] = ss[5] = word_in(key, 5);
-
-#ifdef ENC_KS_UNROLL
- ke6(cx->ks, 0); ke6(cx->ks, 1);
- ke6(cx->ks, 2); ke6(cx->ks, 3);
- ke6(cx->ks, 4); ke6(cx->ks, 5);
- ke6(cx->ks, 6);
-#else
- { uint_32t i;
- for(i = 0; i < 7; ++i)
- ke6(cx->ks, i);
- }
-#endif
- kef6(cx->ks, 7);
- cx->inf.l = 0;
- cx->inf.b[0] = 12 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_256) || defined( AES_VAR )
-
-#define kef8(k,i) \
-{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
- k[8*(i)+ 9] = ss[1] ^= ss[0]; \
- k[8*(i)+10] = ss[2] ^= ss[1]; \
- k[8*(i)+11] = ss[3] ^= ss[2]; \
-}
-
-#define ke8(k,i) \
-{ kef8(k,i); \
- k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
- k[8*(i)+13] = ss[5] ^= ss[4]; \
- k[8*(i)+14] = ss[6] ^= ss[5]; \
- k[8*(i)+15] = ss[7] ^= ss[6]; \
-}
-
-AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
-{ uint_32t ss[8];
-
- cx->ks[0] = ss[0] = word_in(key, 0);
- cx->ks[1] = ss[1] = word_in(key, 1);
- cx->ks[2] = ss[2] = word_in(key, 2);
- cx->ks[3] = ss[3] = word_in(key, 3);
- cx->ks[4] = ss[4] = word_in(key, 4);
- cx->ks[5] = ss[5] = word_in(key, 5);
- cx->ks[6] = ss[6] = word_in(key, 6);
- cx->ks[7] = ss[7] = word_in(key, 7);
-
-#ifdef ENC_KS_UNROLL
- ke8(cx->ks, 0); ke8(cx->ks, 1);
- ke8(cx->ks, 2); ke8(cx->ks, 3);
- ke8(cx->ks, 4); ke8(cx->ks, 5);
-#else
- { uint_32t i;
- for(i = 0; i < 6; ++i)
- ke8(cx->ks, i);
- }
-#endif
- kef8(cx->ks, 6);
- cx->inf.l = 0;
- cx->inf.b[0] = 14 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_VAR )
-
-AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
-{
- switch(key_len)
- {
- case 16: case 128: return aes_encrypt_key128(key, cx);
- case 24: case 192: return aes_encrypt_key192(key, cx);
- case 32: case 256: return aes_encrypt_key256(key, cx);
- default: return EXIT_FAILURE;
- }
-}
-
-#endif
-
-#endif
-
-#if (FUNCS_IN_C & DEC_KEYING_IN_C)
-
-/* this is used to store the decryption round keys */
-/* in forward or reverse order */
-
-#ifdef AES_REV_DKS
-#define v(n,i) ((n) - (i) + 2 * ((i) & 3))
-#else
-#define v(n,i) (i)
-#endif
-
-#if DEC_ROUND == NO_TABLES
-#define ff(x) (x)
-#else
-#define ff(x) inv_mcol(x)
-#if defined( dec_imvars )
-#define d_vars dec_imvars
-#endif
-#endif
-
-#if defined(AES_128) || defined( AES_VAR )
-
-#define k4e(k,i) \
-{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
- k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
- k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
- k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
-}
-
-#if 1
-
-#define kdf4(k,i) \
-{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
- ss[1] = ss[1] ^ ss[3]; \
- ss[2] = ss[2] ^ ss[3]; \
- ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
- ss[i % 4] ^= ss[4]; \
- ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
- ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
- ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
- ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
-}
-
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
- ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
- k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
- k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
- k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
- k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
-}
-
-#define kdl4(k,i) \
-{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
- k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
- k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
- k[v(40,(4*(i))+6)] = ss[0]; \
- k[v(40,(4*(i))+7)] = ss[1]; \
-}
-
-#else
-
-#define kdf4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
- ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
- ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
-}
-
-#define kd4(k,i) \
-{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
- ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
- ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
- ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
- ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
-}
-
-#define kdl4(k,i) \
-{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
- ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
- ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
- ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
-}
-
-#endif
-
-AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
-{ uint_32t ss[5];
-#if defined( d_vars )
- d_vars;
-#endif
- cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
- cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
- cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
- cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
- kdf4(cx->ks, 0); kd4(cx->ks, 1);
- kd4(cx->ks, 2); kd4(cx->ks, 3);
- kd4(cx->ks, 4); kd4(cx->ks, 5);
- kd4(cx->ks, 6); kd4(cx->ks, 7);
- kd4(cx->ks, 8); kdl4(cx->ks, 9);
-#else
- { uint_32t i;
- for(i = 0; i < 10; ++i)
- k4e(cx->ks, i);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 10 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#endif
- cx->inf.l = 0;
- cx->inf.b[0] = 10 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_192) || defined( AES_VAR )
-
-#define k6ef(k,i) \
-{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
- k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
- k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
- k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
-}
-
-#define k6e(k,i) \
-{ k6ef(k,i); \
- k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
- k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
-}
-
-#define kdf6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
- ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
- ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
- ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
- ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
-}
-
-#define kd6(k,i) \
-{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
- ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
- ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
- ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
- ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
- ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
- ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
-}
-
-#define kdl6(k,i) \
-{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
- ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
- ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
- ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
-}
-
-AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
-{ uint_32t ss[7];
-#if defined( d_vars )
- d_vars;
-#endif
- cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
- cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
- cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
- cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
- cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
- cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
- kdf6(cx->ks, 0); kd6(cx->ks, 1);
- kd6(cx->ks, 2); kd6(cx->ks, 3);
- kd6(cx->ks, 4); kd6(cx->ks, 5);
- kd6(cx->ks, 6); kdl6(cx->ks, 7);
-#else
- cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
- cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
- { uint_32t i;
-
- for(i = 0; i < 7; ++i)
- k6e(cx->ks, i);
- k6ef(cx->ks, 7);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 12 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#endif
- cx->inf.l = 0;
- cx->inf.b[0] = 12 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_256) || defined( AES_VAR )
-
-#define k8ef(k,i) \
-{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
- k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
- k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
- k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
-}
-
-#define k8e(k,i) \
-{ k8ef(k,i); \
- k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
- k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
- k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
- k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
-}
-
-#define kdf8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
- ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
- ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
- ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
- ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
- ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
- ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
- ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
-}
-
-#define kd8(k,i) \
-{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
- ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
- ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
- ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
- ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
- ss[8] = ls_box(ss[3],0); \
- ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
- ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
- ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
- ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
-}
-
-#define kdl8(k,i) \
-{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
- ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
- ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
- ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
-}
-
-AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
-{ uint_32t ss[9];
-#if defined( d_vars )
- d_vars;
-#endif
- cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
- cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
- cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
- cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
- cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
- cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
- cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
- cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
- kdf8(cx->ks, 0); kd8(cx->ks, 1);
- kd8(cx->ks, 2); kd8(cx->ks, 3);
- kd8(cx->ks, 4); kd8(cx->ks, 5);
- kdl8(cx->ks, 6);
-#else
- cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
- cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
- cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
- cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
- { uint_32t i;
-
- for(i = 0; i < 6; ++i)
- k8e(cx->ks, i);
- k8ef(cx->ks, 6);
-#if !(DEC_ROUND == NO_TABLES)
- for(i = N_COLS; i < 14 * N_COLS; ++i)
- cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
- }
-#endif
- cx->inf.l = 0;
- cx->inf.b[0] = 14 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
- if(VIA_ACE_AVAILABLE)
- cx->inf.b[1] = 0xff;
-#endif
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_VAR )
-
-AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
-{
- switch(key_len)
- {
- case 16: case 128: return aes_decrypt_key128(key, cx);
- case 24: case 192: return aes_decrypt_key192(key, cx);
- case 32: case 256: return aes_decrypt_key256(key, cx);
- default: return EXIT_FAILURE;
- }
-}
-
-#endif
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aesopt.h b/jni/libzrtp/sources/cryptcommon/aesopt.h
deleted file mode 100644
index 471e0c9..0000000
--- a/jni/libzrtp/sources/cryptcommon/aesopt.h
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the compilation options for AES (Rijndael) and code
- that is common across encryption, key scheduling and table generation.
-
- OPERATION
-
- These source code files implement the AES algorithm Rijndael designed by
- Joan Daemen and Vincent Rijmen. This version is designed for the standard
- block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
- and 32 bytes).
-
- This version is designed for flexibility and speed using operations on
- 32-bit words rather than operations on bytes. It can be compiled with
- either big or little endian internal byte order but is faster when the
- native byte order for the processor is used.
-
- THE CIPHER INTERFACE
-
- The cipher interface is implemented as an array of bytes in which lower
- AES bit sequence indexes map to higher numeric significance within bytes.
-
- uint_8t (an unsigned 8-bit type)
- uint_32t (an unsigned 32-bit type)
- struct aes_encrypt_ctx (structure for the cipher encryption context)
- struct aes_decrypt_ctx (structure for the cipher decryption context)
- AES_RETURN the function return type
-
- C subroutine calls:
-
- AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
- AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
- AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
- AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
- const aes_encrypt_ctx cx[1]);
-
- AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
- AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
- AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
- AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
- const aes_decrypt_ctx cx[1]);
-
- IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
- you call aes_init() before AES is used so that the tables are initialised.
-
- C++ aes class subroutines:
-
- Class AESencrypt for encryption
-
- Construtors:
- AESencrypt(void)
- AESencrypt(const unsigned char *key) - 128 bit key
- Members:
- AES_RETURN key128(const unsigned char *key)
- AES_RETURN key192(const unsigned char *key)
- AES_RETURN key256(const unsigned char *key)
- AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
-
- Class AESdecrypt for encryption
- Construtors:
- AESdecrypt(void)
- AESdecrypt(const unsigned char *key) - 128 bit key
- Members:
- AES_RETURN key128(const unsigned char *key)
- AES_RETURN key192(const unsigned char *key)
- AES_RETURN key256(const unsigned char *key)
- AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
-*/
-
-#if !defined( _AESOPT_H )
-#define _AESOPT_H
-
-#if defined( __cplusplus )
-#include "aescpp.h"
-#else
-#include "aes.h"
-#endif
-
-/* PLATFORM SPECIFIC INCLUDES */
-
-#include "brg_endian.h"
-
-/* CONFIGURATION - THE USE OF DEFINES
-
- Later in this section there are a number of defines that control the
- operation of the code. In each section, the purpose of each define is
- explained so that the relevant form can be included or excluded by
- setting either 1's or 0's respectively on the branches of the related
- #if clauses. The following local defines should not be changed.
-*/
-
-#define ENCRYPTION_IN_C 1
-#define DECRYPTION_IN_C 2
-#define ENC_KEYING_IN_C 4
-#define DEC_KEYING_IN_C 8
-
-#define NO_TABLES 0
-#define ONE_TABLE 1
-#define FOUR_TABLES 4
-#define NONE 0
-#define PARTIAL 1
-#define FULL 2
-
-/* --- START OF USER CONFIGURED OPTIONS --- */
-
-/* 1. BYTE ORDER WITHIN 32 BIT WORDS
-
- The fundamental data processing units in Rijndael are 8-bit bytes. The
- input, output and key input are all enumerated arrays of bytes in which
- bytes are numbered starting at zero and increasing to one less than the
- number of bytes in the array in question. This enumeration is only used
- for naming bytes and does not imply any adjacency or order relationship
- from one byte to another. When these inputs and outputs are considered
- as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
- byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
- In this implementation bits are numbered from 0 to 7 starting at the
- numerically least significant end of each byte (bit n represents 2^n).
-
- However, Rijndael can be implemented more efficiently using 32-bit
- words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
- into word[n]. While in principle these bytes can be assembled into words
- in any positions, this implementation only supports the two formats in
- which bytes in adjacent positions within words also have adjacent byte
- numbers. This order is called big-endian if the lowest numbered bytes
- in words have the highest numeric significance and little-endian if the
- opposite applies.
-
- This code can work in either order irrespective of the order used by the
- machine on which it runs. Normally the internal byte order will be set
- to the order of the processor on which the code is to be run but this
- define can be used to reverse this in special situations
-
- WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
- This define will hence be redefined later (in section 4) if necessary
-*/
-
-#if 1
-# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif 0
-# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
-#elif 0
-# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
-#else
-# error The algorithm byte order is not defined
-#endif
-
-/* 2. VIA ACE SUPPORT */
-
-#if defined( __GNUC__ ) && defined( __i386__ ) \
- || defined( _WIN32 ) && defined( _M_IX86 ) \
- && !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
-# define VIA_ACE_POSSIBLE
-#endif
-
-/* Define this option if support for the VIA ACE is required. This uses
- inline assembler instructions and is only implemented for the Microsoft,
- Intel and GCC compilers. If VIA ACE is known to be present, then defining
- ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
- code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
- it is detected (both present and enabled) but the normal AES code will
- also be present.
-
- When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
- aligned; other input/output buffers do not need to be 16 byte aligned
- but there are very large performance gains if this can be arranged.
- VIA ACE also requires the decryption key schedule to be in reverse
- order (which later checks below ensure).
-*/
-
-#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
-# define USE_VIA_ACE_IF_PRESENT
-#endif
-
-#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
-# define ASSUME_VIA_ACE_PRESENT
-# endif
-
-/* 3. ASSEMBLER SUPPORT
-
- This define (which can be on the command line) enables the use of the
- assembler code routines for encryption, decryption and key scheduling
- as follows:
-
- ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
- encryption and decryption and but with key scheduling in C
- ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
- encryption, decryption and key scheduling
- ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
- encryption and decryption and but with key scheduling in C
- ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
- encryption and decryption and but with key scheduling in C
-
- Change one 'if 0' below to 'if 1' to select the version or define
- as a compilation option.
-*/
-
-#if 0 && !defined( ASM_X86_V1C )
-# define ASM_X86_V1C
-#elif 0 && !defined( ASM_X86_V2 )
-# define ASM_X86_V2
-#elif 0 && !defined( ASM_X86_V2C )
-# define ASM_X86_V2C
-#elif 0 && !defined( ASM_AMD64_C )
-# define ASM_AMD64_C
-#endif
-
-#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
- && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )
-# error Assembler code is only available for x86 and AMD64 systems
-#endif
-
-/* 4. FAST INPUT/OUTPUT OPERATIONS.
-
- On some machines it is possible to improve speed by transferring the
- bytes in the input and output arrays to and from the internal 32-bit
- variables by addressing these arrays as if they are arrays of 32-bit
- words. On some machines this will always be possible but there may
- be a large performance penalty if the byte arrays are not aligned on
- the normal word boundaries. On other machines this technique will
- lead to memory access errors when such 32-bit word accesses are not
- properly aligned. The option SAFE_IO avoids such problems but will
- often be slower on those machines that support misaligned access
- (especially so if care is taken to align the input and output byte
- arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
- assumed that access to byte arrays as if they are arrays of 32-bit
- words will not cause problems when such accesses are misaligned.
-*/
-#if 1 && !defined( _MSC_VER )
-# define SAFE_IO
-#endif
-
-/* 5. LOOP UNROLLING
-
- The code for encryption and decrytpion cycles through a number of rounds
- that can be implemented either in a loop or by expanding the code into a
- long sequence of instructions, the latter producing a larger program but
- one that will often be much faster. The latter is called loop unrolling.
- There are also potential speed advantages in expanding two iterations in
- a loop with half the number of iterations, which is called partial loop
- unrolling. The following options allow partial or full loop unrolling
- to be set independently for encryption and decryption
-*/
-#if 1
-# define ENC_UNROLL FULL
-#elif 0
-# define ENC_UNROLL PARTIAL
-#else
-# define ENC_UNROLL NONE
-#endif
-
-#if 1
-# define DEC_UNROLL FULL
-#elif 0
-# define DEC_UNROLL PARTIAL
-#else
-# define DEC_UNROLL NONE
-#endif
-
-#if 1
-# define ENC_KS_UNROLL
-#endif
-
-#if 1
-# define DEC_KS_UNROLL
-#endif
-
-/* 6. FAST FINITE FIELD OPERATIONS
-
- If this section is included, tables are used to provide faster finite
- field arithmetic (this has no effect if FIXED_TABLES is defined).
-*/
-#if 1
-# define FF_TABLES
-#endif
-
-/* 7. INTERNAL STATE VARIABLE FORMAT
-
- The internal state of Rijndael is stored in a number of local 32-bit
- word varaibles which can be defined either as an array or as individual
- names variables. Include this section if you want to store these local
- varaibles in arrays. Otherwise individual local variables will be used.
-*/
-#if 1
-# define ARRAYS
-#endif
-
-/* 8. FIXED OR DYNAMIC TABLES
-
- When this section is included the tables used by the code are compiled
- statically into the binary file. Otherwise the subroutine aes_init()
- must be called to compute them before the code is first used.
-*/
-#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
-# define FIXED_TABLES
-#endif
-
-/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
-
- In some systems it is better to mask longer values to extract bytes
- rather than using a cast. This option allows this choice.
-*/
-#if 0
-# define to_byte(x) ((uint_8t)(x))
-#else
-# define to_byte(x) ((x) & 0xff)
-#endif
-
-/* 10. TABLE ALIGNMENT
-
- On some sytsems speed will be improved by aligning the AES large lookup
- tables on particular boundaries. This define should be set to a power of
- two giving the desired alignment. It can be left undefined if alignment
- is not needed. This option is specific to the Microsft VC++ compiler -
- it seems to sometimes cause trouble for the VC++ version 6 compiler.
-*/
-
-#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
-# define TABLE_ALIGN 32
-#endif
-
-/* 11. REDUCE CODE AND TABLE SIZE
-
- This replaces some expanded macros with function calls if AES_ASM_V2 or
- AES_ASM_V2C are defined
-*/
-
-#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
-# define REDUCE_CODE_SIZE
-#endif
-
-/* 12. TABLE OPTIONS
-
- This cipher proceeds by repeating in a number of cycles known as 'rounds'
- which are implemented by a round function which can optionally be speeded
- up using tables. The basic tables are each 256 32-bit words, with either
- one or four tables being required for each round function depending on
- how much speed is required. The encryption and decryption round functions
- are different and the last encryption and decrytpion round functions are
- different again making four different round functions in all.
-
- This means that:
- 1. Normal encryption and decryption rounds can each use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
- 2. The last encryption and decryption rounds can also use either 0, 1
- or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-
- Include or exclude the appropriate definitions below to set the number
- of tables used by this implementation.
-*/
-
-#if 1 /* set tables for the normal encryption round */
-# define ENC_ROUND FOUR_TABLES
-#elif 0
-# define ENC_ROUND ONE_TABLE
-#else
-# define ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last encryption round */
-# define LAST_ENC_ROUND FOUR_TABLES
-#elif 0
-# define LAST_ENC_ROUND ONE_TABLE
-#else
-# define LAST_ENC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the normal decryption round */
-# define DEC_ROUND FOUR_TABLES
-#elif 0
-# define DEC_ROUND ONE_TABLE
-#else
-# define DEC_ROUND NO_TABLES
-#endif
-
-#if 1 /* set tables for the last decryption round */
-# define LAST_DEC_ROUND FOUR_TABLES
-#elif 0
-# define LAST_DEC_ROUND ONE_TABLE
-#else
-# define LAST_DEC_ROUND NO_TABLES
-#endif
-
-/* The decryption key schedule can be speeded up with tables in the same
- way that the round functions can. Include or exclude the following
- defines to set this requirement.
-*/
-#if 1
-# define KEY_SCHED FOUR_TABLES
-#elif 0
-# define KEY_SCHED ONE_TABLE
-#else
-# define KEY_SCHED NO_TABLES
-#endif
-
-/* ---- END OF USER CONFIGURED OPTIONS ---- */
-
-/* VIA ACE support is only available for VC++ and GCC */
-
-#if !defined( _MSC_VER ) && !defined( __GNUC__ )
-# if defined( ASSUME_VIA_ACE_PRESENT )
-# undef ASSUME_VIA_ACE_PRESENT
-# endif
-# if defined( USE_VIA_ACE_IF_PRESENT )
-# undef USE_VIA_ACE_IF_PRESENT
-# endif
-#endif
-
-#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
-# define USE_VIA_ACE_IF_PRESENT
-#endif
-
-#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
-# define AES_REV_DKS
-#endif
-
-/* ********** UNDEF - we don't use VIA stuff ****************** */
-#undef USE_VIA_ACE_IF_PRESENT
-
-/* Assembler support requires the use of platform byte order */
-
-#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
- && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
-# undef ALGORITHM_BYTE_ORDER
-# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
-#endif
-
-/* In this implementation the columns of the state array are each held in
- 32-bit words. The state array can be held in various ways: in an array
- of words, in a number of individual word variables or in a number of
- processor registers. The following define maps a variable name x and
- a column number c to the way the state array variable is to be held.
- The first define below maps the state into an array x[c] whereas the
- second form maps the state into a number of individual variables x0,
- x1, etc. Another form could map individual state colums to machine
- register names.
-*/
-
-#if defined( ARRAYS )
-# define s(x,c) x[c]
-#else
-# define s(x,c) x##c
-#endif
-
-/* This implementation provides subroutines for encryption, decryption
- and for setting the three key lengths (separately) for encryption
- and decryption. Since not all functions are needed, masks are set
- up here to determine which will be implemented in C
-*/
-
-#if !defined( AES_ENCRYPT )
-# define EFUNCS_IN_C 0
-#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
- || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
-# define EFUNCS_IN_C ENC_KEYING_IN_C
-#elif !defined( ASM_X86_V2 )
-# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
-#else
-# define EFUNCS_IN_C 0
-#endif
-
-#if !defined( AES_DECRYPT )
-# define DFUNCS_IN_C 0
-#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
- || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
-# define DFUNCS_IN_C DEC_KEYING_IN_C
-#elif !defined( ASM_X86_V2 )
-# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
-#else
-# define DFUNCS_IN_C 0
-#endif
-
-#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
-
-/* END OF CONFIGURATION OPTIONS */
-
-#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
-
-/* Disable or report errors on some combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-# undef LAST_ENC_ROUND
-# define LAST_ENC_ROUND NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-# undef LAST_ENC_ROUND
-# define LAST_ENC_ROUND ONE_TABLE
-#endif
-
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-# undef ENC_UNROLL
-# define ENC_UNROLL NONE
-#endif
-
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-# undef LAST_DEC_ROUND
-# define LAST_DEC_ROUND NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-# undef LAST_DEC_ROUND
-# define LAST_DEC_ROUND ONE_TABLE
-#endif
-
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-# undef DEC_UNROLL
-# define DEC_UNROLL NONE
-#endif
-
-#if defined( bswap32 )
-# define aes_sw32 bswap32
-#elif defined( bswap_32 )
-# define aes_sw32 bswap_32
-#else
-# define brot(x,n) (((uint_32t)(x) << n) | ((uint_32t)(x) >> (32 - n)))
-# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
-#endif
-
-/* upr(x,n): rotates bytes within words by n positions, moving bytes to
- higher index positions with wrap around into low positions
- ups(x,n): moves bytes by n positions to higher index positions in
- words but without wrap around
- bval(x,n): extracts a byte from a word
-
- WARNING: The definitions given here are intended only for use with
- unsigned variables and with shift counts that are compile
- time constants
-*/
-
-#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
-# define upr(x,n) (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))
-# define ups(x,n) ((uint_32t) (x) << (8 * (n)))
-# define bval(x,n) to_byte((x) >> (8 * (n)))
-# define bytes2word(b0, b1, b2, b3) \
- (((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))
-#endif
-
-#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
-# define upr(x,n) (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))
-# define ups(x,n) ((uint_32t) (x) >> (8 * (n)))
-# define bval(x,n) to_byte((x) >> (24 - 8 * (n)))
-# define bytes2word(b0, b1, b2, b3) \
- (((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))
-#endif
-
-#if defined( SAFE_IO )
-# define word_in(x,c) bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \
- ((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])
-# define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \
- ((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }
-#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
-# define word_in(x,c) (*((uint_32t*)(x)+(c)))
-# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))
-#else
-# define word_in(x,c) aes_sw32(*((uint_32t*)(x)+(c)))
-# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))
-#endif
-
-/* the finite field modular polynomial and elements */
-
-#define WPOLY 0x011b
-#define BPOLY 0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define gf_c1 0x80808080
-#define gf_c2 0x7f7f7f7f
-#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
-
-/* The following defines provide alternative definitions of gf_mulx that might
- give improved performance if a fast 32-bit multiply is not available. Note
- that a temporary variable u needs to be defined where gf_mulx is used.
-
-#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
-#define gf_c4 (0x01010101 * BPOLY)
-#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
-*/
-
-/* Work out which tables are needed for the different options */
-
-#if defined( ASM_X86_V1C )
-# if defined( ENC_ROUND )
-# undef ENC_ROUND
-# endif
-# define ENC_ROUND FOUR_TABLES
-# if defined( LAST_ENC_ROUND )
-# undef LAST_ENC_ROUND
-# endif
-# define LAST_ENC_ROUND FOUR_TABLES
-# if defined( DEC_ROUND )
-# undef DEC_ROUND
-# endif
-# define DEC_ROUND FOUR_TABLES
-# if defined( LAST_DEC_ROUND )
-# undef LAST_DEC_ROUND
-# endif
-# define LAST_DEC_ROUND FOUR_TABLES
-# if defined( KEY_SCHED )
-# undef KEY_SCHED
-# define KEY_SCHED FOUR_TABLES
-# endif
-#endif
-
-#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
-# if ENC_ROUND == ONE_TABLE
-# define FT1_SET
-# elif ENC_ROUND == FOUR_TABLES
-# define FT4_SET
-# else
-# define SBX_SET
-# endif
-# if LAST_ENC_ROUND == ONE_TABLE
-# define FL1_SET
-# elif LAST_ENC_ROUND == FOUR_TABLES
-# define FL4_SET
-# elif !defined( SBX_SET )
-# define SBX_SET
-# endif
-#endif
-
-#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
-# if DEC_ROUND == ONE_TABLE
-# define IT1_SET
-# elif DEC_ROUND == FOUR_TABLES
-# define IT4_SET
-# else
-# define ISB_SET
-# endif
-# if LAST_DEC_ROUND == ONE_TABLE
-# define IL1_SET
-# elif LAST_DEC_ROUND == FOUR_TABLES
-# define IL4_SET
-# elif !defined(ISB_SET)
-# define ISB_SET
-# endif
-#endif
-
-#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
-# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
-# if KEY_SCHED == ONE_TABLE
-# if !defined( FL1_SET ) && !defined( FL4_SET )
-# define LS1_SET
-# endif
-# elif KEY_SCHED == FOUR_TABLES
-# if !defined( FL4_SET )
-# define LS4_SET
-# endif
-# elif !defined( SBX_SET )
-# define SBX_SET
-# endif
-# endif
-# if (FUNCS_IN_C & DEC_KEYING_IN_C)
-# if KEY_SCHED == ONE_TABLE
-# define IM1_SET
-# elif KEY_SCHED == FOUR_TABLES
-# define IM4_SET
-# elif !defined( SBX_SET )
-# define SBX_SET
-# endif
-# endif
-#endif
-
-/* generic definitions of Rijndael macros that use tables */
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
- box[bval(vf(x,0,c),rf(0,c))], \
- box[bval(vf(x,1,c),rf(1,c))], \
- box[bval(vf(x,2,c),rf(2,c))], \
- box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- ( tab[bval(vf(x,0,c),rf(0,c))] \
- ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
- ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
- ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- ( tab[0][bval(vf(x,0,c),rf(0,c))] \
- ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
- ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
- ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c) (x)
-#define rf1(r,c) (r)
-#define rf2(r,c) ((8+r-c)&3)
-
-/* perform forward and inverse column mix operation on four bytes in long word x in */
-/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
-
-#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
-
-#if defined( FM4_SET ) /* not currently used */
-# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
-#elif defined( FM1_SET ) /* not currently used */
-# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
-#else
-# define dec_fmvars uint_32t g2
-# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
-#endif
-
-#if defined( IM4_SET )
-# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
-#elif defined( IM1_SET )
-# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
-#else
-# define dec_imvars uint_32t g2, g4, g9
-# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
- (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
-#endif
-
-#if defined( FL4_SET )
-# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
-#elif defined( LS4_SET )
-# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
-#elif defined( FL1_SET )
-# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
-#elif defined( LS1_SET )
-# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
-#else
-# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
-#endif
-
-#endif
-
-#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
-# define ISB_SET
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aestab.c b/jni/libzrtp/sources/cryptcommon/aestab.c
deleted file mode 100644
index e2bdb9a..0000000
--- a/jni/libzrtp/sources/cryptcommon/aestab.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#define DO_TABLES
-
-#include "aes.h"
-#include "aesopt.h"
-
-#if defined(FIXED_TABLES)
-
-#define sb_data(w) {\
- w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
- w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
- w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
- w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
- w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
- w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
- w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
- w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
- w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
- w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
- w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
- w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
- w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
- w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
- w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
- w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
- w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
- w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
- w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
- w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
- w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
- w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
- w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
- w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
- w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
- w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
- w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
- w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
- w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
- w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
- w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
- w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
-
-#define isb_data(w) {\
- w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
- w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
- w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
- w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
- w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
- w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
- w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
- w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
- w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
- w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
- w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
- w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
- w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
- w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
- w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
- w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
- w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
- w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
- w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
- w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
- w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
- w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
- w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
- w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
- w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
- w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
- w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
- w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
- w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
- w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
- w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
- w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
-
-#define mm_data(w) {\
- w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
- w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
- w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
- w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
- w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
- w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
- w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
- w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
- w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
- w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
- w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
- w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
- w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
- w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
- w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
- w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
- w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
- w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
- w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
- w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
- w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
- w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
- w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
- w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
- w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
- w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
- w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
- w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
- w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
- w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
- w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
- w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
-
-#define rc_data(w) {\
- w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
- w(0x1b), w(0x36) }
-
-#define h0(x) (x)
-
-#define w0(p) bytes2word(p, 0, 0, 0)
-#define w1(p) bytes2word(0, p, 0, 0)
-#define w2(p) bytes2word(0, 0, p, 0)
-#define w3(p) bytes2word(0, 0, 0, p)
-
-#define u0(p) bytes2word(f2(p), p, p, f3(p))
-#define u1(p) bytes2word(f3(p), f2(p), p, p)
-#define u2(p) bytes2word(p, f3(p), f2(p), p)
-#define u3(p) bytes2word(p, p, f3(p), f2(p))
-
-#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
-#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
-#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
-#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
-
-#endif
-
-#if defined(FIXED_TABLES) || !defined(FF_TABLES)
-
-#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
- ^ (((x>>5) & 4) * WPOLY))
-#define f3(x) (f2(x) ^ x)
-#define f9(x) (f8(x) ^ x)
-#define fb(x) (f8(x) ^ f2(x) ^ x)
-#define fd(x) (f8(x) ^ f4(x) ^ x)
-#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
-
-#else
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-
-#endif
-
-#include "aestab.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined(FIXED_TABLES)
-
-/* implemented in case of wrong call for fixed tables */
-
-AES_RETURN aes_init(void)
-{
- return EXIT_SUCCESS;
-}
-
-#else /* Generate the tables for the dynamic table option */
-
-#if defined(FF_TABLES)
-
-#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0)
-
-#else
-
-/* It will generally be sensible to use tables to compute finite
- field multiplies and inverses but where memory is scarse this
- code might sometimes be better. But it only has effect during
- initialisation so its pretty unimportant in overall terms.
-*/
-
-/* return 2 ^ (n - 1) where n is the bit number of the highest bit
- set in x with x in the range 1 < x < 0x00000200. This form is
- used so that locals within fi can be bytes rather than words
-*/
-
-static uint_8t hibit(const uint_32t x)
-{ uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
-
- r |= (r >> 2);
- r |= (r >> 4);
- return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static uint_8t gf_inv(const uint_8t x)
-{ uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
- if(x < 2)
- return x;
-
- for( ; ; )
- {
- if(n1)
- while(n2 >= n1) /* divide polynomial p2 by p1 */
- {
- n2 /= n1; /* shift smaller polynomial left */
- p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
- v2 ^= v1 * n2; /* shift accumulated value and */
- n2 = hibit(p2); /* add into result */
- }
- else
- return v1;
-
- if(n2) /* repeat with values swapped */
- while(n1 >= n2)
- {
- n1 /= n2;
- p1 ^= p2 * n1;
- v1 ^= v2 * n1;
- n1 = hibit(p1);
- }
- else
- return v2;
- }
-}
-
-#endif
-
-/* The forward and inverse affine transformations used in the S-box */
-uint_8t fwd_affine(const uint_8t x)
-{ uint_32t w = x;
- w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
- return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
-}
-
-uint_8t inv_affine(const uint_8t x)
-{ uint_32t w = x;
- w = (w << 1) ^ (w << 3) ^ (w << 6);
- return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
-}
-
-static int init = 0;
-
-AES_RETURN aes_init(void)
-{ uint_32t i, w;
-
-#if defined(FF_TABLES)
-
- uint_8t pow[512], log[256];
-
- if(init)
- return EXIT_SUCCESS;
- /* log and power tables for GF(2^8) finite field with
- WPOLY as modular polynomial - the simplest primitive
- root is 0x03, used here to generate the tables
- */
-
- i = 0; w = 1;
- do
- {
- pow[i] = (uint_8t)w;
- pow[i + 255] = (uint_8t)w;
- log[w] = (uint_8t)i++;
- w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
- }
- while (w != 1);
-
-#else
- if(init)
- return EXIT_SUCCESS;
-#endif
-
- for(i = 0, w = 1; i < RC_LENGTH; ++i)
- {
- t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
- w = f2(w);
- }
-
- for(i = 0; i < 256; ++i)
- { uint_8t b;
-
- b = fwd_affine(gf_inv((uint_8t)i));
- w = bytes2word(f2(b), b, b, f3(b));
-
-#if defined( SBX_SET )
- t_set(s,box)[i] = b;
-#endif
-
-#if defined( FT1_SET ) /* tables for a normal encryption round */
- t_set(f,n)[i] = w;
-#endif
-#if defined( FT4_SET )
- t_set(f,n)[0][i] = w;
- t_set(f,n)[1][i] = upr(w,1);
- t_set(f,n)[2][i] = upr(w,2);
- t_set(f,n)[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-
-#if defined( FL1_SET ) /* tables for last encryption round (may also */
- t_set(f,l)[i] = w; /* be used in the key schedule) */
-#endif
-#if defined( FL4_SET )
- t_set(f,l)[0][i] = w;
- t_set(f,l)[1][i] = upr(w,1);
- t_set(f,l)[2][i] = upr(w,2);
- t_set(f,l)[3][i] = upr(w,3);
-#endif
-
-#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
- t_set(l,s)[i] = w; /* not of the required form */
-#endif
-#if defined( LS4_SET )
- t_set(l,s)[0][i] = w;
- t_set(l,s)[1][i] = upr(w,1);
- t_set(l,s)[2][i] = upr(w,2);
- t_set(l,s)[3][i] = upr(w,3);
-#endif
-
- b = gf_inv(inv_affine((uint_8t)i));
- w = bytes2word(fe(b), f9(b), fd(b), fb(b));
-
-#if defined( IM1_SET ) /* tables for the inverse mix column operation */
- t_set(i,m)[b] = w;
-#endif
-#if defined( IM4_SET )
- t_set(i,m)[0][b] = w;
- t_set(i,m)[1][b] = upr(w,1);
- t_set(i,m)[2][b] = upr(w,2);
- t_set(i,m)[3][b] = upr(w,3);
-#endif
-
-#if defined( ISB_SET )
- t_set(i,box)[i] = b;
-#endif
-#if defined( IT1_SET ) /* tables for a normal decryption round */
- t_set(i,n)[i] = w;
-#endif
-#if defined( IT4_SET )
- t_set(i,n)[0][i] = w;
- t_set(i,n)[1][i] = upr(w,1);
- t_set(i,n)[2][i] = upr(w,2);
- t_set(i,n)[3][i] = upr(w,3);
-#endif
- w = bytes2word(b, 0, 0, 0);
-#if defined( IL1_SET ) /* tables for last decryption round */
- t_set(i,l)[i] = w;
-#endif
-#if defined( IL4_SET )
- t_set(i,l)[0][i] = w;
- t_set(i,l)[1][i] = upr(w,1);
- t_set(i,l)[2][i] = upr(w,2);
- t_set(i,l)[3][i] = upr(w,3);
-#endif
- }
- init = 1;
- return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
diff --git a/jni/libzrtp/sources/cryptcommon/aestab.h b/jni/libzrtp/sources/cryptcommon/aestab.h
deleted file mode 100644
index de68567..0000000
--- a/jni/libzrtp/sources/cryptcommon/aestab.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the code for declaring the tables needed to implement
- AES. The file aesopt.h is assumed to be included before this header file.
- If there are no global variables, the definitions here can be used to put
- the AES tables in a structure so that a pointer can then be added to the
- AES context to pass them to the AES routines that need them. If this
- facility is used, the calling program has to ensure that this pointer is
- managed appropriately. In particular, the value of the t_dec(in,it) item
- in the table structure must be set to zero in order to ensure that the
- tables are initialised. In practice the three code sequences in aeskey.c
- that control the calls to aes_init() and the aes_init() routine itself will
- have to be changed for a specific implementation. If global variables are
- available it will generally be preferable to use them with the precomputed
- FIXED_TABLES option that uses static global tables.
-
- The following defines can be used to control the way the tables
- are defined, initialised and used in embedded environments that
- require special features for these purposes
-
- the 't_dec' construction is used to declare fixed table arrays
- the 't_set' construction is used to set fixed table values
- the 't_use' construction is used to access fixed table values
-
- 256 byte tables:
-
- t_xxx(s,box) => forward S box
- t_xxx(i,box) => inverse S box
-
- 256 32-bit word OR 4 x 256 32-bit word tables:
-
- t_xxx(f,n) => forward normal round
- t_xxx(f,l) => forward last round
- t_xxx(i,n) => inverse normal round
- t_xxx(i,l) => inverse last round
- t_xxx(l,s) => key schedule table
- t_xxx(i,m) => key schedule table
-
- Other variables and tables:
-
- t_xxx(r,c) => the rcon table
-*/
-
-#if !defined( _AESTAB_H )
-#define _AESTAB_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#define t_dec(m,n) t_##m##n
-#define t_set(m,n) t_##m##n
-#define t_use(m,n) t_##m##n
-
-#if defined(FIXED_TABLES)
-# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
-/* make tables far data to avoid using too much DGROUP space (PG) */
-# define CONST const far
-# else
-# define CONST const
-# endif
-#else
-# define CONST
-#endif
-
-#if defined(DO_TABLES)
-# define EXTERN
-#else
-# define EXTERN extern
-#endif
-
-#if defined(_MSC_VER) && defined(TABLE_ALIGN)
-#define ALIGN __declspec(align(TABLE_ALIGN))
-#else
-#define ALIGN
-#endif
-
-#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
-# define XP_DIR __cdecl
-#else
-# define XP_DIR
-#endif
-
-#if defined(DO_TABLES) && defined(FIXED_TABLES)
-#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e)
-#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
-EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
-#else
-#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256]
-#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
-EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];
-#endif
-
-#if defined( SBX_SET )
- d_1(uint_8t, t_dec(s,box), sb_data, h0);
-#endif
-#if defined( ISB_SET )
- d_1(uint_8t, t_dec(i,box), isb_data, h0);
-#endif
-
-#if defined( FT1_SET )
- d_1(uint_32t, t_dec(f,n), sb_data, u0);
-#endif
-#if defined( FT4_SET )
- d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
-#endif
-
-#if defined( FL1_SET )
- d_1(uint_32t, t_dec(f,l), sb_data, w0);
-#endif
-#if defined( FL4_SET )
- d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
-#endif
-
-#if defined( IT1_SET )
- d_1(uint_32t, t_dec(i,n), isb_data, v0);
-#endif
-#if defined( IT4_SET )
- d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
-#endif
-
-#if defined( IL1_SET )
- d_1(uint_32t, t_dec(i,l), isb_data, w0);
-#endif
-#if defined( IL4_SET )
- d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
-#endif
-
-#if defined( LS1_SET )
-#if defined( FL1_SET )
-#undef LS1_SET
-#else
- d_1(uint_32t, t_dec(l,s), sb_data, w0);
-#endif
-#endif
-
-#if defined( LS4_SET )
-#if defined( FL4_SET )
-#undef LS4_SET
-#else
- d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);
-#endif
-#endif
-
-#if defined( IM1_SET )
- d_1(uint_32t, t_dec(i,m), mm_data, v0);
-#endif
-#if defined( IM4_SET )
- d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/brg_types.h b/jni/libzrtp/sources/cryptcommon/brg_types.h
deleted file mode 100644
index 40d4af5..0000000
--- a/jni/libzrtp/sources/cryptcommon/brg_types.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
-
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- The unsigned integer types defined here are of the form uint_<nn>t where
- <nn> is the length of the type; for example, the unsigned 32-bit type is
- 'uint_32t'. These are NOT the same as the 'C99 integer types' that are
- defined in the inttypes.h and stdint.h headers since attempts to use these
- types have shown that support for them is still highly variable. However,
- since the latter are of the form uint<nn>_t, a regular expression search
- and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
- can be used to convert the types used here to the C99 standard types.
-*/
-
-#ifndef _BRG_TYPES_H
-#define _BRG_TYPES_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#include <limits.h>
-
-#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
-# include <stddef.h>
-# define ptrint_t intptr_t
-#elif defined( __ECOS__ )
-# define intptr_t unsigned int
-# define ptrint_t intptr_t
-#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )
-# include <stdint.h>
-# define ptrint_t intptr_t
-#else
-# define ptrint_t int
-#endif
-
-#ifndef BRG_UI8
-# define BRG_UI8
-# if UCHAR_MAX == 255u
- typedef unsigned char uint_8t;
-# else
-# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h
-# endif
-#endif
-
-#ifndef BRG_UI16
-# define BRG_UI16
-# if USHRT_MAX == 65535u
- typedef unsigned short uint_16t;
-# else
-# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h
-# endif
-#endif
-
-#ifndef BRG_UI32
-# define BRG_UI32
-# if UINT_MAX == 4294967295u
-# define li_32(h) 0x##h##u
- typedef unsigned int uint_32t;
-# elif ULONG_MAX == 4294967295u
-# define li_32(h) 0x##h##ul
- typedef unsigned long uint_32t;
-# elif defined( _CRAY )
-# error This code needs 32-bit data types, which Cray machines do not provide
-# else
-# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h
-# endif
-#endif
-
-#ifndef BRG_UI64
-# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
-# define BRG_UI64
-# define li_64(h) 0x##h##ui64
- typedef unsigned __int64 uint_64t;
-# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
-# define BRG_UI64
-# define li_64(h) 0x##h##ui64
- typedef unsigned __int64 uint_64t;
-# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
-# define BRG_UI64
-# define li_64(h) 0x##h##ull
- typedef unsigned long long uint_64t;
-# elif defined( __MVS__ )
-# define BRG_UI64
-# define li_64(h) 0x##h##ull
- typedef unsigned int long long uint_64t;
-# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
-# if UINT_MAX == 18446744073709551615u
-# define BRG_UI64
-# define li_64(h) 0x##h##u
- typedef unsigned int uint_64t;
-# endif
-# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
-# if ULONG_MAX == 18446744073709551615ul
-# define BRG_UI64
-# define li_64(h) 0x##h##ul
- typedef unsigned long uint_64t;
-# endif
-# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
-# if ULLONG_MAX == 18446744073709551615ull
-# define BRG_UI64
-# define li_64(h) 0x##h##ull
- typedef unsigned long long uint_64t;
-# endif
-# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
-# if ULONG_LONG_MAX == 18446744073709551615ull
-# define BRG_UI64
-# define li_64(h) 0x##h##ull
- typedef unsigned long long uint_64t;
-# endif
-# endif
-#endif
-
-#if !defined( BRG_UI64 )
-# if defined( NEED_UINT_64T )
-# error Please define uint_64t as an unsigned 64 bit type in brg_types.h
-# endif
-#endif
-
-#ifndef RETURN_VALUES
-# define RETURN_VALUES
-# if defined( DLL_EXPORT )
-# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
-# define VOID_RETURN __declspec( dllexport ) void __stdcall
-# define INT_RETURN __declspec( dllexport ) int __stdcall
-# elif defined( __GNUC__ )
-# define VOID_RETURN __declspec( __dllexport__ ) void
-# define INT_RETURN __declspec( __dllexport__ ) int
-# else
-# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
-# endif
-# elif defined( DLL_IMPORT )
-# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
-# define VOID_RETURN __declspec( dllimport ) void __stdcall
-# define INT_RETURN __declspec( dllimport ) int __stdcall
-# elif defined( __GNUC__ )
-# define VOID_RETURN __declspec( __dllimport__ ) void
-# define INT_RETURN __declspec( __dllimport__ ) int
-# else
-# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
-# endif
-# elif defined( __WATCOMC__ )
-# define VOID_RETURN void __cdecl
-# define INT_RETURN int __cdecl
-# else
-# define VOID_RETURN void
-# define INT_RETURN int
-# endif
-#endif
-
-/* These defines are used to detect and set the memory alignment of pointers.
- Note that offsets are in bytes.
-
- ALIGN_OFFSET(x,n) return the positive or zero offset of
- the memory addressed by the pointer 'x'
- from an address that is aligned on an
- 'n' byte boundary ('n' is a power of 2)
-
- ALIGN_FLOOR(x,n) return a pointer that points to memory
- that is aligned on an 'n' byte boundary
- and is not higher than the memory address
- pointed to by 'x' ('n' is a power of 2)
-
- ALIGN_CEIL(x,n) return a pointer that points to memory
- that is aligned on an 'n' byte boundary
- and is not lower than the memory address
- pointed to by 'x' ('n' is a power of 2)
-*/
-
-#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
-#define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
-#define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
-
-/* These defines are used to declare buffers in a way that allows
- faster operations on longer variables to be used. In all these
- defines 'size' must be a power of 2 and >= 8. NOTE that the
- buffer size is in bytes but the type length is in bits
-
- UNIT_TYPEDEF(x,size) declares a variable 'x' of length
- 'size' bits
-
- BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize'
- bytes defined as an array of variables
- each of 'size' bits (bsize must be a
- multiple of size / 8)
-
- UNIT_CAST(x,size) casts a variable to a type of
- length 'size' bits
-
- UPTR_CAST(x,size) casts a pointer to a pointer to a
- varaiable of length 'size' bits
-*/
-
-#define UI_TYPE(size) uint_##size##t
-#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
-#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
-#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
-#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x))
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/demo/CMakeLists.txt b/jni/libzrtp/sources/demo/CMakeLists.txt
index c253d9f..8db3c63 100755
--- a/jni/libzrtp/sources/demo/CMakeLists.txt
+++ b/jni/libzrtp/sources/demo/CMakeLists.txt
@@ -1,27 +1,15 @@
+########### next target ###############
-#to make sure includes are first taken - it contains config.h
-include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/zrtp
- ${CMAKE_SOURCE_DIR}/clients/ccrtp)
+add_executable(zrtptest zrtptest.cpp)
+target_link_libraries(zrtptest zrtpcpp)
+add_dependencies(zrtptest zrtpcpp)
-if (CCRTP)
- ########### next target ###############
+########### next target ###############
- add_executable(zrtptest zrtptest.cpp)
- target_link_libraries(zrtptest ${zrtplibName})
- add_dependencies(zrtptest ${zrtplibName})
+add_executable(zrtptestMulti zrtptestMulti.cpp)
+target_link_libraries(zrtptestMulti zrtpcpp)
+add_dependencies(zrtptestMulti zrtpcpp)
- ########### next target ###############
-
- add_executable(zrtptestMulti zrtptestMulti.cpp)
- target_link_libraries(zrtptestMulti ${zrtplibName})
- add_dependencies(zrtptestMulti ${zrtplibName})
-else()
- add_executable(sdestest sdestest.cpp)
- target_link_libraries(sdestest ${zrtplibName})
- add_dependencies(sdestest ${zrtplibName})
-endif()
########### next target ###############
#add_executable(wrappertest wrappertest.c)
diff --git a/jni/libzrtp/sources/demo/sdestest.cpp b/jni/libzrtp/sources/demo/sdestest.cpp
deleted file mode 100644
index a329e8d..0000000
--- a/jni/libzrtp/sources/demo/sdestest.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <crypto/hmac256.h>
-
-/*
-HKDF-Expand(PRK, info, L)
-
-Description in RFC 5869
-
- HKDF-Expand(PRK, info, L) -> OKM
-
- Options:
- Hash a hash function; HashLen denotes the length of the
- hash function output in octets
- Inputs:
- PRK a pseudorandom key of at least HashLen octets
- (usually, the output from the extract step)
- info optional context and application specific information
- (can be a zero-length string)
- L length of output keying material in octets
- (<= 255*HashLen)
-
- Output:
- OKM output keying material (of L octets)
-
- The output OKM is calculated as follows:
-
- N = ceil(L/HashLen)
- T = T(1) | T(2) | T(3) | ... | T(N)
- OKM = first L octets of T
-
- where:
- T(0) = empty string (zero length)
- T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
- T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
- T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
- ...
-
- (where the constant concatenated to the end of each T(n) is a
- single octet.)
-
-
- A.1. Test Case 1
-
- Basic test case with SHA-256
-
- Hash = SHA-256
- IKM = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b (22 octets)
- salt = 0x000102030405060708090a0b0c (13 octets)
- info = 0xf0f1f2f3f4f5f6f7f8f9 (10 octets)
- L = 42
-
- PRK = 0x077709362c2e32df0ddc3f0dc47bba63
- 90b6c73bb50f9c3122ec844ad7c2b3e5 (32 octets)
- OKM = 0x3cb25f25faacd57a90434f64d0362f2a
- 2d2d0a90cf1a5a4c5db02d56ecc4c5bf
- 34007208d5b887185865 (42 octets)
-
-A.2. Test Case 2
-
- Test with SHA-256 and longer inputs/outputs
-
- Hash = SHA-256
- IKM = 0x000102030405060708090a0b0c0d0e0f
- 101112131415161718191a1b1c1d1e1f
- 202122232425262728292a2b2c2d2e2f
- 303132333435363738393a3b3c3d3e3f
- 404142434445464748494a4b4c4d4e4f (80 octets)
- salt = 0x606162636465666768696a6b6c6d6e6f
- 707172737475767778797a7b7c7d7e7f
- 808182838485868788898a8b8c8d8e8f
- 909192939495969798999a9b9c9d9e9f
- a0a1a2a3a4a5a6a7a8a9aaabacadaeaf (80 octets)
- info = 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf
- c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
- d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
- e0e1e2e3e4e5e6e7e8e9eaebecedeeef
- f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff (80 octets)
- L = 82
-
- PRK = 0x06a6b88c5853361a06104c9ceb35b45c
- ef760014904671014a193f40c15fc244 (32 octets)
- OKM = 0xb11e398dc80327a1c8e7f78c596a4934
- 4f012eda2d4efad8a050cc4c19afa97c
- 59045a99cac7827271cb41c65e590e09
- da3275600c2f09b8367793a9aca3db71
- cc30c58179ec3e87c14c01d5c1f3434f
- 1d87 (82 octets)
-
-A.3. Test Case 3
-
- Test with SHA-256 and zero-length salt/info
-
- Hash = SHA-256
- IKM = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b (22 octets)
- salt = (0 octets)
- info = (0 octets)
- L = 42
-
- PRK = 0x19ef24a32c717b167f33a91d6f648bdf
- 96596776afdb6377ac434c1c293ccb04 (32 octets)
- OKM = 0x8da4e775a563c18f715f802a063c5a31
- b8a11f5c5ee1879ec3454e5f3c738d2d
- 9d201395faa4b61a96c8 (42 octets)
-
-*/
-
-static void hexdump(const char* title, const unsigned char *s, int l)
-{
- int n=0;
-
- if (s == NULL) return;
-
- fprintf(stderr, "%s",title);
- for( ; n < l ; ++n) {
- if((n%16) == 0)
- fprintf(stderr, "\n%04x",n);
- fprintf(stderr, " %02x",s[n]);
- }
- fprintf(stderr, "\n");
-}
-
-
-static uint8_t info_A1[] = {
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
-
-static int32_t L_A1 = 42;
-
-static uint8_t PRK_A1[] = {
- 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
- 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
-
-static uint8_t OKM_A1[] = {
- 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
- 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
- 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65}; // (42 octets)
-
-
-static int32_t L_A3 = 42;
-
-static uint8_t PRK_A3[] = {
- 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
- 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77, 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04}; // (32 octets)
-
-static uint8_t OKM_A3[] = {
- 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
- 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
- 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8}; // (42 octets)
-
-
-
-void* createSha256HmacContext(uint8_t* key, int32_t keyLength);
-void freeSha256HmacContext(void* ctx);
-void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength );
-
-
-static int expand(uint8_t* prk, uint32_t prkLen, uint8_t* info, int32_t infoLen, int32_t L, uint32_t hashLen, uint8_t* outbuffer)
-{
- int32_t n;
- uint8_t *T;
- void* hmacCtx;
-
- const uint8_t* data[4]; // Data pointers for HMAC data, max. 3 plus terminating NULL
- uint32_t dataLen[4];
- int32_t dataIdx = 0;
-
- uint8_t counter;
- int32_t macLength;
-
- if (prkLen < hashLen)
- return -1;
-
- n = (L + (hashLen-1)) / hashLen;
-
- // T points to buffer that holds concatenated T(1) || T(2) || ... T(N))
- T = reinterpret_cast<uint8_t*>(malloc(n * hashLen));
-
- // Prepare the HMAC
- hmacCtx = createSha256HmacContext(prk, prkLen);
-
- // Prepare first HMAC. T(0) has zero length, thus we ignore it in first run.
- // After first run use its output (T(1)) as first data in next HMAC run.
- for (int i = 1; i <= n; i++) {
- if (infoLen > 0 && info != NULL) {
- data[dataIdx] = info;
- dataLen[dataIdx++] = infoLen;
- }
- counter = i & 0xff;
- data[dataIdx] = &counter;
- dataLen[dataIdx++] = 1;
-
- data[dataIdx] = NULL;
- dataLen[dataIdx++] = 0;
-
- hmacSha256Ctx(hmacCtx, data, dataLen, T + ((i-1) * hashLen), &macLength);
-
- dataIdx = 0;
- data[dataIdx] = T + ((i-1) * hashLen);
- dataLen[dataIdx++] = hashLen;
- }
- freeSha256HmacContext(hmacCtx);
- memcpy(outbuffer, T, L);
- free(T);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- uint8_t buffer[500];
- expand(PRK_A1, sizeof(PRK_A1), info_A1, sizeof(info_A1), L_A1, SHA256_DIGEST_LENGTH, buffer);
- if (memcmp(buffer, OKM_A1, L_A1) != 0) {
- fprintf(stderr, "ERROR: Test result A1 mismatch");
- hexdump("Computed result of expand A1", buffer, L_A1);
- hexdump("Expected result of expand A1", OKM_A1, L_A1);
- return 1;
- }
-
- expand(PRK_A3, sizeof(PRK_A3), NULL, 0, L_A3, SHA256_DIGEST_LENGTH, buffer);
- if (memcmp(buffer, OKM_A3, L_A3) != 0) {
- fprintf(stderr, "ERROR: Test result A3 mismatch");
- hexdump("Computed result of expand A3", buffer, L_A3);
- hexdump("Expected result of expand A3", OKM_A3, L_A3);
- return 1;
- }
-
- printf("Done\n");
- return 0;
-}
diff --git a/jni/libzrtp/sources/demo/zrtptest.cpp b/jni/libzrtp/sources/demo/zrtptest.cpp
index 0595543..394d31c 100644
--- a/jni/libzrtp/sources/demo/zrtptest.cpp
+++ b/jni/libzrtp/sources/demo/zrtptest.cpp
@@ -18,7 +18,7 @@
#include <cstdlib>
#include <map>
-#include <zrtpccrtp.h>
+#include <libzrtpcpp/zrtpccrtp.h>
#include <libzrtpcpp/ZrtpUserCallback.h>
using namespace ost;
@@ -28,36 +28,40 @@
class PacketsPattern
{
public:
- inline const InetHostAddress& getReceiverAddress() const { return *receiverAddress; }
- inline const InetHostAddress& getSenderAddress() const { return *senderAddress; }
+ inline const InetHostAddress&
+ getDestinationAddress() const
+ { return destinationAddress; }
- inline void setReceiverAddress(InetHostAddress *addr) const { delete receiverAddress; receiverAddress = addr; }
- inline void setSenderAddress(InetHostAddress *addr) const { delete senderAddress; senderAddress = addr; }
+ inline const tpport_t
+ getDestinationPort() const
+ { return destinationPort; }
- inline const tpport_t getReceiverPort() const { return receiverPort; }
- inline const tpport_t getSenderPort() const { return senderPort; }
+ uint32
+ getPacketsNumber() const
+ { return packetsNumber; }
- uint32 getPacketsNumber() const { return packetsNumber; }
+ uint32
+ getSsrc() const
+ { return 0xdeadbeef; }
- uint32 getSsrc() const { return 0xdeadbeef; }
+ const unsigned char*
+ getPacketData(uint32 i)
+ { return data[i%2]; }
- const unsigned char*getPacketData(uint32 i) { return data[i%2]; }
-
- const size_t getPacketSize(uint32 i) { return strlen((char*)data[i%2]) + 1 ; }
+ const size_t
+ getPacketSize(uint32 i)
+ { return strlen((char*)data[i%2]) + 1 ; }
private:
- static const InetHostAddress *receiverAddress;
- static const InetHostAddress *senderAddress;
-
- static const uint16 receiverPort = 5002;
- static const uint16 senderPort = 5004;
+ static const InetHostAddress destinationAddress;
+ static const uint16 destinationPort = 5002;
static const uint32 packetsNumber = 10;
static const uint32 packetsSize = 12;
static const unsigned char* data[];
};
-const InetHostAddress *PacketsPattern::receiverAddress = new InetHostAddress("localhost");
-const InetHostAddress *PacketsPattern::senderAddress = new InetHostAddress("localhost");
+const InetHostAddress PacketsPattern::destinationAddress =
+ InetHostAddress("localhost");
const unsigned char* PacketsPattern::data[] = {
(unsigned char*)"0123456789\n",
@@ -111,13 +115,6 @@
};
-/*
- * The following classes use:
- * - localAddress and destination port+2 for the sender classes
- * - destinationAddress and destination port for the receiver classes.
- *
- */
-
/**
* SymmetricZRTPSession in non-security mode (RTPSession compatible).
*
@@ -135,7 +132,7 @@
int doTest() {
// should be valid?
//RTPSession tx();
- ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
+ ExtZrtpSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
// SymmetricZRTPSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
tx.setSchedulingTimeout(10000);
tx.setExpireTimeout(1000000);
@@ -143,9 +140,8 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
-
- // We are sender:
- if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+ if (!tx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()) ) {
return 1;
}
@@ -178,7 +174,8 @@
int
doTest() {
- ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
+ ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
+ pattern.getDestinationPort());
// SymmetricZRTPSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
// pattern.getDestinationPort());
@@ -188,7 +185,8 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+ if (!rx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()+2) ) {
return 1;
}
for ( int i = 0; i < 5000 ; i++ ) {
@@ -227,8 +225,8 @@
int doTest() {
// should be valid?
//RTPSession tx();
- // Initialize with local address and Local port is detination port +2 - keep RTP/RTCP port pairs
- ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
+ ExtZrtpSession tx(pattern.getSsrc(), pattern.getDestinationAddress(),
+ pattern.getDestinationPort()+2);
tx.initialize("test_t.zid");
tx.setSchedulingTimeout(10000);
@@ -237,7 +235,8 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
- if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+ if (!tx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()) ) {
return 1;
}
tx.startZrtp();
@@ -269,7 +268,8 @@
int
doTest() {
- ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
+ ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
+ pattern.getDestinationPort());
rx.initialize("test_r.zid");
@@ -279,7 +279,8 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+ if (!rx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()+2) ) {
return 1;
}
rx.startZrtp();
@@ -344,8 +345,6 @@
warningMap.insert(pair<int32, std::string*>(WarningCRCmismatch, new string("Internal ZRTP packet checksum mismatch - packet dropped")));
warningMap.insert(pair<int32, std::string*>(WarningSRTPauthError, new string("Dropping packet because SRTP authentication failed!")));
warningMap.insert(pair<int32, std::string*>(WarningSRTPreplayError, new string("Dropping packet because SRTP replay check failed!")));
- warningMap.insert(pair<int32, std::string*>(WarningNoExpectedRSMatch, new string("No RS match found - but ZRTP expected a match.")));
- warningMap.insert(pair<int32, std::string*>(WarningNoExpectedAuxMatch, new string("The auxlliary secrets do not match.")));
severeMap.insert(pair<int32, std::string*>(SevereHelloHMACFailed, new string("Hash HMAC check of Hello failed!")));
severeMap.insert(pair<int32, std::string*>(SevereCommitHMACFailed, new string("Hash HMAC check of Commit failed!")));
@@ -451,8 +450,6 @@
bool MyUserCallback::initialized = false;
-static unsigned char transmAuxSecret[] = {1,2,3,4,5,6,7,8,9,0};
-
/**
* SymmetricZRTPSession in security mode and using a callback class.
*
@@ -468,55 +465,26 @@
ZrtpSendPacketTransmissionTestCB : public Thread, public TimerPort
{
public:
-
- ZrtpConfigure config;
-
- void run() {
+ void
+ run()
+ {
doTest();
}
- int doTest() {
+ int doTest()
+ {
// should be valid?
//RTPSession tx();
- ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getSenderAddress(), pattern.getSenderPort());
- config.clear();
-// config.setStandardConfig();
-// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
-// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
-
- // This ordering prefers NIST
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
-
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
-
- config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
- config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
-
- config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
- config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
-
- config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
- config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
- config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
- config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
- config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
-
- tx.initialize("test_t.zid", true, &config);
+ ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getDestinationAddress(),
+ pattern.getDestinationPort()+2);
+ tx.initialize("test_t.zid");
// At this point the Hello hash is available. See ZRTP specification
// chapter 9.1 for further information when an how to use the Hello
// hash.
- int numSupportedVersion = tx.getNumberSupportedVersions();
- cout << "TX Hello hash 0: " << tx.getHelloHash(0) << endl;
- cout << "TX Hello hash 0 length: " << tx.getHelloHash(0).length() << endl;
- if (numSupportedVersion > 1) {
- cout << "TX Hello hash 1: " << tx.getHelloHash(1) << endl;
- cout << "TX Hello hash 1 length: " << tx.getHelloHash(1).length() << endl;
- }
+ cout << "TX Hello hash: " << tx.getHelloHash() << endl;
+ cout << "TX Hello hash length: " << tx.getHelloHash().length() << endl;
+
tx.setUserCallback(new MyUserCallback(&tx));
- tx.setAuxSecret(transmAuxSecret, sizeof(transmAuxSecret));
tx.setSchedulingTimeout(10000);
tx.setExpireTimeout(1000000);
@@ -524,8 +492,8 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
-
- if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+ if (!tx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()) ) {
return 1;
}
tx.startZrtp();
@@ -549,49 +517,29 @@
}
};
-static unsigned char recvAuxSecret[] = {1,2,3,4,5,6,7,8,9,9};
class
ZrtpRecvPacketTransmissionTestCB: public Thread
{
public:
- ZrtpConfigure config;
-
- void run() {
+ void
+ run() {
doTest();
}
- int doTest() {
- ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getReceiverAddress(), pattern.getReceiverPort());
- config.clear();
-// config.setStandardConfig();
-// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
+ int
+ doTest() {
+ ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getDestinationAddress(),
+ pattern.getDestinationPort());
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
-
- config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
- config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
-
-// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
-// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
-
- config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
-
- rx.initialize("test_r.zid", true, &config);
+ rx.initialize("test_r.zid");
// At this point the Hello hash is available. See ZRTP specification
// chapter 9.1 for further information when an how to use the Hello
// hash.
- int numSupportedVersion = rx.getNumberSupportedVersions();
- cout << "RX Hello hash 0: " << rx.getHelloHash(0) << endl;
- cout << "RX Hello hash 0 length: " << rx.getHelloHash(0).length() << endl;
- if (numSupportedVersion > 1) {
- cout << "RX Hello hash 1: " << rx.getHelloHash(1) << endl;
- cout << "RX Hello hash 1 length: " << rx.getHelloHash(1).length() << endl;
- }
+ cout << "RX Hello hash: " << rx.getHelloHash() << endl;
+ cout << "RX Hello hash length: " << rx.getHelloHash().length() << endl;
+
rx.setUserCallback(new MyUserCallback(&rx));
- rx.setAuxSecret(recvAuxSecret, sizeof(recvAuxSecret));
rx.setSchedulingTimeout(10000);
rx.setExpireTimeout(1000000);
@@ -599,7 +547,8 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+ if (!rx.addDestination(pattern.getDestinationAddress(),
+ pattern.getDestinationPort()+2) ) {
return 1;
}
rx.startZrtp();
@@ -631,7 +580,7 @@
/* check args */
while (1) {
- c = getopt(argc, argv, "rsR:S:");
+ c = getopt(argc, argv, "rs");
if (c == -1) {
break;
}
@@ -642,12 +591,6 @@
case 's':
send = true;
break;
- case 'R':
- pattern.setReceiverAddress(new InetHostAddress(optarg));
- break;
- case 'S':
- pattern.setSenderAddress(new InetHostAddress(optarg));
- break;
default:
cerr << "Wrong Arguments, only -s and -r are accepted" << endl;
}
diff --git a/jni/libzrtp/sources/demo/zrtptestMulti.cpp b/jni/libzrtp/sources/demo/zrtptestMulti.cpp
index d7042ed..39e20a7 100644
--- a/jni/libzrtp/sources/demo/zrtptestMulti.cpp
+++ b/jni/libzrtp/sources/demo/zrtptestMulti.cpp
@@ -18,7 +18,7 @@
#include <cstdlib>
#include <map>
-#include <zrtpccrtp.h>
+#include <libzrtpcpp/zrtpccrtp.h>
#include <libzrtpcpp/ZrtpUserCallback.h>
#include <libzrtpcpp/ZrtpConfigure.h>
@@ -488,8 +488,7 @@
if (!multiParams.empty()) {
tx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
pattern.getDestinationPort()+2+10);
-
- // tx->initialize("test_t.zid", true, &config);
+// tx->initialize("test_t.zid", true, &config);
tx->initialize("test_t.zid", true);
tx->setMultiStrParams(multiParams);
@@ -500,12 +499,13 @@
else {
tx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
pattern.getDestinationPort()+2);
+ //config.addHashAlgo(Sha384);
+// tx->initialize("test_t.zid", true, &config);
if (mitm) { // Act as trusted MitM - could be enrolled
tx->setMitmMode(true);
}
tx->setSignSas(signsas);
-// tx->initialize("test_t.zid", true, &config);
tx->initialize("test_t.zid", true);
if (enroll) // act as PBX enrollement service
@@ -518,13 +518,8 @@
// At this point the Hello hash is available. See ZRTP specification
// chapter 9.1 for further information when an how to use the Hello
// hash.
- int numSupportedVersion = tx->getNumberSupportedVersions();
- cout << "TX Hello hash 0: " << tx->getHelloHash(0) << endl;
- cout << "TX Hello hash 0 length: " << tx->getHelloHash(0).length() << endl;
- if (numSupportedVersion > 1) {
- cout << "TX Hello hash 1: " << tx->getHelloHash(1) << endl;
- cout << "TX Hello hash 1 length: " << tx->getHelloHash(1).length() << endl;
- }
+ cout << prefix << "Hello hash: " << tx->getHelloHash() << endl;
+ cout << prefix << "Hello hash length: " << tx->getHelloHash().length() << endl;
tx->setUserCallback(mcb);
tx->setSchedulingTimeout(10000);
tx->setExpireTimeout(1000000);
@@ -588,14 +583,12 @@
rx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
pattern.getDestinationPort());
config.setStandardConfig();
-// config.clear();
-// config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
if (enroll)
config.setTrustedMitM(true); // allow a trusted MitM to start enrollment process
rx->setSignSas(signsas);
+ // config.addHashAlgo(Sha384);
rx->initialize("test_r.zid", true, &config);
// rx->initialize("test_r.zid", true);
@@ -606,13 +599,8 @@
// At this point the Hello hash is available. See ZRTP specification
// chapter 9.1 for further information when an how to use the Hello
// hash.
- int numSupportedVersion = rx->getNumberSupportedVersions();
- cout << "RX Hello hash 0: " << rx->getHelloHash(0) << endl;
- cout << "RX Hello hash 0 length: " << rx->getHelloHash(0).length() << endl;
- if (numSupportedVersion > 1) {
- cout << "RX Hello hash 1: " << rx->getHelloHash(1) << endl;
- cout << "RX Hello hash 1 length: " << rx->getHelloHash(1).length() << endl;
- }
+ cout << prefix << "Hello hash: " << rx->getHelloHash() << endl;
+ cout << prefix << "Hello hash length: " << rx->getHelloHash().length() << endl;
rx->setUserCallback(mcb);
rx->setSchedulingTimeout(10000);
rx->setExpireTimeout(1000000);
diff --git a/jni/libzrtp/sources/doc/Doxymini b/jni/libzrtp/sources/doc/Doxymini
index 245ff07..2685d6e 100644
--- a/jni/libzrtp/sources/doc/Doxymini
+++ b/jni/libzrtp/sources/doc/Doxymini
@@ -1,243 +1,211 @@
-# Doxyfile 1.7.5.1
+# Doxyfile 1.5.3
# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
+# doxygen (www.doxygen.org) for a project
#
-# All text after a hash (#) is considered a comment and will be ignored.
+# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ").
+# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
+# This tag specifies the encoding used for all characters in the config file that
+# follow. The default is UTF-8 which is also the encoding used for all text before
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+# possible encodings.
DOXYFILE_ENCODING = UTF-8
-# The PROJECT_NAME tag is a single word (or sequence of words) that should
-# identify the project. Note that if you do not use Doxywizard you need
-# to put quotes around the project name if it contains spaces.
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
-PROJECT_NAME = "ZRTP and SRTP implementation"
+PROJECT_NAME = "ZRTP for ccRTP "
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER =
+PROJECT_NUMBER =
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer
-# a quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF =
-
-# With the PROJECT_LOGO tag one can specify an logo or icon that is
-# included in the documentation. The maximum height of the logo should not
-# exceed 55 pixels and the maximum width should not exceed 200 pixels.
-# Doxygen will copy the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = .
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
CREATE_SUBDIRS = NO
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
OUTPUT_LANGUAGE = English
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"
-ABBREVIATE_BRIEF =
+ABBREVIATE_BRIEF =
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
# path to strip.
-STRIP_FROM_PATH =
+STRIP_FROM_PATH =
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
-STRIP_FROM_INC_PATH =
+STRIP_FROM_INC_PATH =
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful if your file system
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF = YES
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF = NO
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS = NO
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.
SEPARATE_MEMBER_PAGES = NO
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
-TAB_SIZE = 4
+TAB_SIZE = 8
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
-ALIASES =
+ALIASES =
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = NO
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this
-# tag. The format is ext=language, where ext is a file extension, and language
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also makes the inheritance and collaboration
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT = NO
@@ -247,542 +215,406 @@
CPP_CLI_SUPPORT = NO
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING = YES
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
-# unions are shown inside the group in which they are included (e.g. using
-# @ingroup) instead of on a separate page (for HTML and Man pages) or
-# section (for LaTeX and RTF).
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
-# unions with only public data fields will be shown inline in the documentation
-# of the scope in which they are defined (i.e. file, namespace, or group
-# documentation), provided this scope is documented. If set to NO (the default),
-# structs, classes, and unions are shown on a separate page (for HTML and Man
-# pages) or section (for LaTeX and RTF).
-
-INLINE_SIMPLE_STRUCTS = NO
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penalty.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will roughly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE = 0
-
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
-EXTRACT_STATIC = YES
+EXTRACT_STATIC = NO
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS = NO
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespaces are hidden.
+# If this flag is set to YES, the members of anonymous namespaces will be extracted
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+# where file will be replaced with the base name of the file that contains the anonymous
+# namespace. By default anonymous namespace are hidden.
EXTRACT_ANON_NSPACES = NO
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.
HIDE_IN_BODY_DOCS = NO
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
CASE_SENSE_NAMES = NO
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
+# Note: This option applies only to the class list, not to the
# alphabetical list.
SORT_BY_SCOPE_NAME = NO
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
-# do proper type resolution of all parameters of a function it will reject a
-# match between the prototype and the implementation of a member function even
-# if there is only one candidate or it is obvious which candidate to choose
-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
-# will still accept a match between prototype and implementation in such cases.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= YES
-# The ENABLED_SECTIONS tag can be used to enable conditional
+# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
-ENABLED_SECTIONS =
+ENABLED_SECTIONS =
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or macro consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and macros in the
-# documentation can be controlled using \showinitializer or \hideinitializer
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = NO
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. The create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option.
-# You can optionally specify a file name after the option, if omitted
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files
-# containing the references data. This must be a list of .bib files. The
-# .bib extension is automatically appended if omitted. Using this command
-# requires the bibtex tool to be installed. See also
-# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
-# of the bibliography can be controlled using LATEX_BIB_STYLE.
-
-CITE_BIB_FILES =
+FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
-# The QUIET tag can be used to turn on/off the messages that are generated
+# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.
WARN_IF_DOC_ERROR = YES
-# The WARN_NO_PARAMDOC option can be enabled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
# documentation.
WARN_NO_PARAMDOC = NO
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
# be obtained via FILE_VERSION_FILTER)
WARN_FORMAT = "$file:$line: $text"
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
# to stderr.
-WARN_LOGFILE =
+WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../zrtp \
- ../zrtp/libzrtpcpp \
- ../zrtp/crypto \
- ../srtp \
- ../srtp/crypto \
- ../clients/ccrtp
+INPUT = ../src \
+ ../src/libzrtpcpp \
+ ../src/libzrtpcpp/crypto
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
+# This tag can be used to specify the character encoding of the source files that
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
INPUT_ENCODING = UTF-8
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
-# *.f90 *.f *.for *.vhd *.vhdl
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
FILE_PATTERNS = *.h
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
-# Note that relative paths are relative to directory from which doxygen is run.
-EXCLUDE =
+EXCLUDE =
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
# from the input.
EXCLUDE_SYMLINKS = NO
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS = config.h \
macros.h \
namespace.h
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the output.
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
-EXCLUDE_SYMBOLS =
+EXCLUDE_SYMBOLS =
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
# the \include command).
-EXAMPLE_PATH =
+EXAMPLE_PATH =
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
-EXAMPLE_PATTERNS =
+EXAMPLE_PATTERNS =
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH =
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
# ignored.
-INPUT_FILTER =
+INPUT_FILTER =
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty or if
-# non of the patterns match the file name, INPUT_FILTER is applied.
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
-FILTER_PATTERNS =
+FILTER_PATTERNS =
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
-# and it is also possible to disable source filtering for a specific pattern
-# using *.ext= (so without naming a filter). This option only has effect when
-# FILTER_SOURCE_FILES is enabled.
-
-FILTER_SOURCE_PATTERNS =
-
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
+# then you must also enable this option. If you don't then doxygen will produce
+# a warning and turn it on anyway
SOURCE_BROWSER = NO
-# Setting the INLINE_SOURCES tag to YES will include the body
+# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = YES
@@ -790,21 +622,20 @@
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
+# link to the source code. Otherwise they will link to the documentstion.
REFERENCES_LINK_SOURCE = YES
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.
USE_HTAGS = NO
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
@@ -813,544 +644,287 @@
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = YES
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
-IGNORE_PREFIX =
+IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT =
+HTML_OUTPUT =
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header. Note that when using a custom header you are responsible
-# for the proper inclusion of any scripts and style sheets that doxygen
-# needs, which is dependent on the configuration options used.
-# It is adviced to generate a default header using "doxygen -w html
-# header.html footer.html stylesheet.css YourConfigFile" and then modify
-# that header. Note that the header is subject to change so you typically
-# have to redo this when upgrading to a newer version of doxygen or when
-# changing the value of configuration settings such as GENERATE_TREEVIEW!
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
-HTML_HEADER =
+HTML_HEADER =
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
-HTML_FOOTER =
+HTML_FOOTER =
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
-HTML_STYLESHEET =
+HTML_STYLESHEET =
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that
-# the files will be copied as-is; there are no commands or markers available.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the stylesheet and background images
-# according to this color. Hue is specified as an angle on a colorwheel,
-# see http://en.wikipedia.org/wiki/Hue for more information.
-# For instance the value 0 represents red, 60 is yellow, 120 is green,
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
-# The allowed range is 0 to 359.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
-# the colors in the HTML output. For a value of 0 the output will use
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
-# the luminance component of the colors in the HTML output. Values below
-# 100 gradually make the output lighter, whereas values above 100 make
-# the output darker. The value divided by 100 is the actual gamma applied,
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
-
-HTML_TIMESTAMP = NO
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-
-GENERATE_DOCSET = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = YES
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
# written to the html output directory.
-CHM_FILE =
+CHM_FILE =
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.
-HHC_LOCATION =
+HHC_LOCATION =
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND = NO
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
-# that can be used as input for Qt's qhelpgenerator to generate a
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
-# add. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS =
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-# will be generated, which together with the HTML files, form an Eclipse help
-# plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
-# the help appears.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML
-# documentation. Note that a value of 0 will completely suppress the enum
-# values from appearing in the overview section.
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
GENERATE_TREEVIEW = NO
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are
-# not supported properly for IE 6.0, but are supported on all modern browsers.
-# Note that when changing this option you need to delete any form_*.png files
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
-# (see http://www.mathjax.org) which uses client side Javascript for the
-# rendering instead of using prerendered bitmaps. Use this if you do not
-# have LaTeX installed or if you want to formulas look prettier in the HTML
-# output. When enabled you also need to install MathJax separately and
-# configure the path to it using the MATHJAX_RELPATH option.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you need to specify the location relative to the
-# HTML output directory using the MATHJAX_RELPATH option. The destination
-# directory should contain the MathJax.js script. For instance, if the mathjax
-# directory is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the
-# mathjax.org site, so you can quickly see the result without installing
-# MathJax, but it is strongly recommended to install a local copy of MathJax
-# before deployment.
-
-MATHJAX_RELPATH = http://www.mathjax.org/mathjax
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
-# names that should be enabled during MathJax rendering.
-
-MATHJAX_EXTENSIONS =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
-# (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvantages are that it is more difficult to setup
-# and does not have live searching capabilities.
-
-SERVER_BASED_SEARCH = NO
-
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
-LATEX_OUTPUT =
+LATEX_OUTPUT =
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
LATEX_CMD_NAME = latex
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, letter, legal and
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
-EXTRA_PACKAGES =
+EXTRA_PACKAGES =
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
-LATEX_HEADER =
+LATEX_HEADER =
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
-# the generated latex document. The footer should contain everything after
-# the last chapter. If it is left blank doxygen will generate a
-# standard footer. Notice: only use this tag if you know what you are doing!
-
-LATEX_FOOTER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES = NO
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
-# http://en.wikipedia.org/wiki/BibTeX for more info.
-
-LATEX_BIB_STYLE = plain
-
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
-RTF_STYLESHEET_FILE =
+RTF_STYLESHEET_FILE =
-# Set optional variables used in the generation of an rtf document.
+# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
-RTF_EXTENSIONS_FILE =
+RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
-MAN_OUTPUT =
+MAN_OUTPUT =
-# The MAN_EXTENSION tag determines the extension that is added to
+# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
@@ -1359,33 +933,33 @@
# configuration options related to the XML output
#---------------------------------------------------------------------------
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML = NO
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.
XML_OUTPUT = xml
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
# syntax of the XML files.
-XML_SCHEMA =
+XML_SCHEMA =
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
# syntax of the XML files.
-XML_DTD =
+XML_DTD =
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING = YES
@@ -1394,10 +968,10 @@
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
@@ -1406,359 +980,319 @@
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
# moment.
GENERATE_PERLMOD = NO
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.
PERLMOD_LATEX = NO
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.
PERLMOD_PRETTY = YES
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.
-PERLMOD_MAKEVAR_PREFIX =
+PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = YES
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
EXPAND_ONLY_PREDEF = NO
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# pointed to by INCLUDE_PATH will be searched when a #include is found.
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH = .
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
-INCLUDE_FILE_PATTERNS =
+INCLUDE_FILE_PATTERNS =
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED =
+PREDEFINED =
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition that
-# overrules the definition found in the source code.
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
-EXPAND_AS_DEFINED =
+EXPAND_AS_DEFINED =
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all references to function-like macros
-# that are alone on a line, have an all uppercase name, and do not end with a
-# semicolon, because these will confuse the parser if not removed.
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration::additions related to external references
#---------------------------------------------------------------------------
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
+# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.
-TAGFILES =
+TAGFILES =
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
-GENERATE_TAGFILE =
+GENERATE_TAGFILE =
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
-# The PERL_PATH should be the absolute path and name of the perl script
+# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration options related to the dot tool
#---------------------------------------------------------------------------
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option also works with HAVE_DOT disabled, but it is recommended to
-# install and use dot, since it yields more powerful graphs.
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
CLASS_DIAGRAMS = YES
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
+# be found in the default search path.
-MSCGEN_PATH =
+MSCGEN_PATH =
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = YES
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS = 0
-
-# By default doxygen will use the Helvetica font for all dot files that
-# doxygen generates. When you want a differently looking font you can specify
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find
-# the font, which can be done by putting it in a standard location or by setting
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
-# directory containing the font.
-
-DOT_FONTNAME = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the Helvetica font.
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
-# set the path where dot can find it.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies
GROUP_GRAPHS = YES
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
UML_LOOK = YES
-# If set to YES, the inheritance and collaboration graphs will show the
+# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
CALL_GRAPH = NO
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a caller dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
CALLER_GRAPH = NO
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will generate a graphical hierarchy of all classes instead of a textual one.
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.
DIRECTORY_GRAPH = YES
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are svg, png, jpg, or gif.
-# If left blank png will be used. If you choose svg you need to set
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible in IE 9+ (other browsers do not have this requirement).
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
DOT_IMAGE_FORMAT = png
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-# Note that this requires a modern browser other than Internet Explorer.
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible. Older versions of IE do not have SVG support.
-
-INTERACTIVE_SVG = NO
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
-DOT_PATH =
+DOT_PATH =
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
# \dotfile command).
-DOTFILE_DIRS =
+DOTFILE_DIRS =
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the
-# \mscfile command).
-
-MSCFILE_DIRS =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the number
+# of direct children of the root node in a graph is already larger than
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
DOT_GRAPH_MAX_NODES = 50
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
MAX_DOT_GRAPH_DEPTH = 0
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
DOT_TRANSPARENT = NO
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
DOT_MULTI_TARGETS = NO
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/jni/libzrtp/sources/libzrtpcpp.pc.cmake b/jni/libzrtp/sources/libzrtpcpp.pc.cmake
index 655bd30..f9f5541 100644
--- a/jni/libzrtp/sources/libzrtpcpp.pc.cmake
+++ b/jni/libzrtp/sources/libzrtpcpp.pc.cmake
@@ -9,7 +9,7 @@
Description: GNU ZRTP core library
Version: @VERSION@
Requires: @CRYPTOBACKEND@
-Libs: -L${libdir} -l@zrtplibName@
+Libs: -L${libdir} -l@zrtplib@
Cflags: -I${includedir}
diff --git a/jni/libzrtp/sources/zrtp/Base32.cpp b/jni/libzrtp/sources/src/Base32.cpp
similarity index 100%
rename from jni/libzrtp/sources/zrtp/Base32.cpp
rename to jni/libzrtp/sources/src/Base32.cpp
diff --git a/jni/libzrtp/sources/src/CMakeLists.txt b/jni/libzrtp/sources/src/CMakeLists.txt
new file mode 100755
index 0000000..05e57ff
--- /dev/null
+++ b/jni/libzrtp/sources/src/CMakeLists.txt
@@ -0,0 +1,87 @@
+cmake_minimum_required (VERSION 2.6)
+
+# add_subdirectory(libzrtpcpp)
+# add_subdirectory(libzrtpcpp/crypto)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+set(gcrypt_src
+ libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
+ libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
+ libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
+ libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
+ libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
+ libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
+ libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp)
+
+set(openssl_src
+ libzrtpcpp/crypto/openssl/ZrtpDH.cpp
+ libzrtpcpp/crypto/openssl/hmac256.cpp
+ libzrtpcpp/crypto/openssl/sha256.cpp
+ libzrtpcpp/crypto/openssl/hmac384.cpp
+ libzrtpcpp/crypto/openssl/sha384.cpp
+ libzrtpcpp/crypto/openssl/AesCFB.cpp
+ libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp)
+
+if (GCRYPT_FOUND)
+ set(crypto_src ${gcrypt_src})
+endif()
+
+if (OPENSSL_FOUND)
+ set(crypto_src ${openssl_src})
+endif()
+
+if(enable_ccrtp)
+ set(ccrtp_src ZrtpQueue.cpp)
+endif()
+
+set(twofish_srcs libzrtpcpp/crypto/twofish.c
+ libzrtpcpp/crypto/twofish_cfb.c
+ libzrtpcpp/crypto/TwoCFB.cpp)
+
+set(zrtp_src
+ ZrtpCallbackWrapper.cpp
+ ZIDFile.cpp
+ ZIDRecord.cpp
+ ZRtp.cpp
+ ZrtpCrc32.cpp
+ ZrtpPacketCommit.cpp
+ ZrtpPacketConf2Ack.cpp
+ ZrtpPacketConfirm.cpp
+ ZrtpPacketDHPart.cpp
+ ZrtpPacketGoClear.cpp
+ ZrtpPacketClearAck.cpp
+ ZrtpPacketHelloAck.cpp
+ ZrtpPacketHello.cpp
+ ZrtpPacketError.cpp
+ ZrtpPacketErrorAck.cpp
+ ZrtpPacketPingAck.cpp
+ ZrtpPacketPing.cpp
+ ZrtpPacketSASrelay.cpp
+ ZrtpPacketRelayAck.cpp
+ ZrtpStateClass.cpp
+ ZrtpTextData.cpp
+ ZrtpConfigure.cpp
+ ZrtpCWrapper.cpp
+ Base32.cpp)
+
+set(zrtpcpp_src ${zrtp_src} ${ccrtp_src} ${crypto_src} ${twofish_srcs})
+
+if(BUILD_STATIC AND NOT BUILD_SHARED)
+ set(LIBRARY_BUILD_TYPE STATIC)
+else()
+ set(LIBRARY_BUILD_TYPE SHARED)
+endif()
+
+add_library(${zrtplib} ${LIBRARY_BUILD_TYPE} ${zrtpcpp_src})
+set_target_properties(${zrtplib} PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION})
+target_link_libraries(${zrtplib} ${LIBS})
+
+if(enable_ccrtp)
+ add_dependencies(${zrtplib} ccrtp)
+endif()
+
+add_subdirectory(libzrtpcpp)
+
+install(TARGETS ${zrtplib} DESTINATION ${LIBDIRNAME})
+
diff --git a/jni/libzrtp/sources/src/ZIDFile.cpp b/jni/libzrtp/sources/src/ZIDFile.cpp
new file mode 100644
index 0000000..69b43eb
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZIDFile.cpp
@@ -0,0 +1,430 @@
+/*
+ Copyright (C) 2006-2008 Werner Dittmann
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+// #define UNIT_TEST
+
+#include <string>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libzrtpcpp/ZIDFile.h>
+
+
+static ZIDFile* instance;
+static int errors = 0; // maybe we will use as member of ZIDFile later...
+
+void ZIDFile::createZIDFile(char* name) {
+ zidFile = fopen(name, "wb+");
+ // New file, generate an associated random ZID and save
+ // it as first record
+ if (zidFile != NULL) {
+ unsigned int* ip;
+ ip = (unsigned int*) associatedZid;
+ srand(time(NULL));
+ *ip++ = rand();
+ *ip++ = rand();
+ *ip = rand();
+
+ ZIDRecord rec(associatedZid);
+ rec.setOwnZIDRecord();
+ fseek(zidFile, 0L, SEEK_SET);
+ if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
+ ++errors;
+ fflush(zidFile);
+ }
+}
+
+/**
+ * Migrate old ZID file format to new one.
+ *
+ * If ZID file is old format:
+ * - close it, rename it, then re-open
+ * - create ZID file for new format
+ * - copy over contents and flags.
+ */
+void ZIDFile::checkDoMigration(char* name) {
+ FILE* fdOld;
+ unsigned char inb[2];
+ zidrecord1_t recOld;
+
+ fseek(zidFile, 0L, SEEK_SET);
+ if (fread(inb, 2, 1, zidFile) < 1) {
+ ++errors;
+ inb[0] = 0;
+ }
+
+ if (inb[0] > 0) { // if it's new format just return
+ return;
+ }
+ fclose(zidFile); // close old ZID file
+ zidFile = NULL;
+
+ // create save file name, rename and re-open
+ // if rename fails, just unlink old ZID file and create a brand new file
+ // just a little inconvenience for the user, need to verify new SAS
+ std::string fn = std::string(name) + std::string(".save");
+ if (rename(name, fn.c_str()) < 0) {
+ unlink(name);
+ createZIDFile(name);
+ return;
+ }
+ fdOld = fopen(fn.c_str(), "rb"); // reopen old format in read only mode
+
+ // Get first record from old file - is the own ZID
+ fseek(fdOld, 0L, SEEK_SET);
+ if (fread(&recOld, sizeof(zidrecord1_t), 1, fdOld) != 1) {
+ fclose(fdOld);
+ return;
+ }
+ if (recOld.ownZid != 1) {
+ fclose(fdOld);
+ return;
+ }
+ zidFile = fopen(name, "wb+"); // create new format file in binary r/w mode
+ if (zidFile == NULL) {
+ return;
+ }
+ // create ZIDRecord in new format, copy over own ZID and write the record
+ ZIDRecord rec(recOld.identifier);
+ rec.setOwnZIDRecord();
+ if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
+ ++errors;
+
+ // now copy over all valid records from old ZID file format.
+ // Sequentially read old records, sequentially write new records
+ int numRead;
+ do {
+ numRead = fread(&recOld, sizeof(zidrecord1_t), 1, fdOld);
+ if (numRead == 0) { // all old records processed
+ break;
+ }
+ // skip own ZID record and invalid records
+ if (recOld.ownZid == 1 || recOld.recValid == 0) {
+ continue;
+ }
+ ZIDRecord rec2(recOld.identifier);
+ rec2.setValid();
+ if (recOld.rs1Valid & SASVerified) {
+ rec2.setSasVerified();
+ }
+ rec2.setNewRs1(recOld.rs2Data);
+ rec2.setNewRs1(recOld.rs1Data);
+ if (fwrite(rec2.getRecordData(), rec2.getRecordLength(), 1, zidFile) < 1)
+ ++errors;
+
+ } while (numRead == 1);
+ fflush(zidFile);
+}
+
+ZIDFile::~ZIDFile() {
+ close();
+}
+
+ZIDFile* ZIDFile::getInstance() {
+
+ if (instance == NULL) {
+ instance = new ZIDFile();
+ }
+ return instance;
+}
+
+int ZIDFile::open(char* name) {
+
+ // check for an already active ZID file
+ if (zidFile != NULL) {
+ return 0;
+ }
+ if ((zidFile = fopen(name, "rb+")) == NULL) {
+ createZIDFile(name);
+ } else {
+ checkDoMigration(name);
+ if (zidFile != NULL) {
+ ZIDRecord rec;
+ fseek(zidFile, 0L, SEEK_SET);
+ if (fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) != 1) {
+ fclose(zidFile);
+ zidFile = NULL;
+ return -1;
+ }
+ if (!rec.isOwnZIDRecord()) {
+ fclose(zidFile);
+ zidFile = NULL;
+ return -1;
+ }
+ memcpy(associatedZid, rec.getIdentifier(), IDENTIFIER_LEN);
+ }
+ }
+ return ((zidFile == NULL) ? -1 : 1);
+}
+
+void ZIDFile::close() {
+
+ if (zidFile != NULL) {
+ fclose(zidFile);
+ zidFile = NULL;
+ }
+}
+
+unsigned int ZIDFile::getRecord(ZIDRecord* zidRecord) {
+ unsigned long pos;
+ ZIDRecord rec;
+ int numRead;
+
+ // set read pointer behind first record (
+ fseek(zidFile, rec.getRecordLength(), SEEK_SET);
+
+ do {
+ pos = ftell(zidFile);
+ numRead = fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile);
+ if (numRead == 0) {
+ break;
+ }
+
+ // skip own ZID record and invalid records
+ if (rec.isOwnZIDRecord() || !rec.isValid()) {
+ continue;
+ }
+
+ } while (numRead == 1 &&
+ memcmp(zidRecord->getIdentifier(), rec.getIdentifier(), IDENTIFIER_LEN) != 0);
+
+ // If we reached end of file, then no record with the ZID
+ // found. We need to create a new ZID record.
+ if (numRead == 0) {
+ // create new record
+ ZIDRecord rec1(zidRecord->getIdentifier());
+ rec1.setValid();
+ if (fwrite(rec1.getRecordData(), rec1.getRecordLength(), 1, zidFile) < 1)
+ ++errors;
+ memcpy(zidRecord->getRecordData(), rec1.getRecordData(), rec1.getRecordLength());
+ } else {
+ // Copy the read data into caller's the record storage
+ memcpy(zidRecord->getRecordData(), rec.getRecordData(), rec.getRecordLength());
+ }
+
+ // remember position of record in file for save operation
+ zidRecord->setPosition(pos);
+ return 1;
+}
+
+unsigned int ZIDFile::saveRecord(ZIDRecord *zidRecord) {
+
+ fseek(zidFile, zidRecord->getPosition(), SEEK_SET);
+ if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
+ ++errors;
+ fflush(zidFile);
+ return 1;
+}
+
+
+#ifdef UNIT_TEST
+
+#include <iostream>
+#include <unistd.h>
+using namespace std;
+
+static void hexdump(const char* title, const unsigned char *s, int l) {
+ int n=0;
+
+ if (s == NULL) return;
+
+ fprintf(stderr, "%s",title);
+ for (; n < l ; ++n) {
+ if ((n%16) == 0)
+ fprintf(stderr, "\n%04x",n);
+ fprintf(stderr, " %02x",s[n]);
+ }
+ fprintf(stderr, "\n");
+}
+
+int main(int argc, char *argv[]) {
+
+ unsigned char myId[IDENTIFIER_LEN];
+ ZIDFile *zid = ZIDFile::getInstance();
+
+ unlink("testzid2");
+ zid->open("testzid2");
+ hexdump("My ZID: ", zid->getZid(), IDENTIFIER_LEN);
+ memcpy(myId, zid->getZid(), IDENTIFIER_LEN);
+ zid->close();
+
+ zid->open("testzid2");
+ if (memcmp(myId, zid->getZid(), IDENTIFIER_LEN) != 0) {
+ cerr << "Wrong ZID in testfile" << endl;
+ return 1;
+ }
+
+ // Create a new ZID record for peer ZID "123456789012"
+ ZIDRecord zr3((unsigned char*) "123456789012");
+ zid->getRecord(&zr3);
+ if (!zr3.isValid()) {
+ cerr << "New ZID record '123456789012' not set to valid" << endl;
+ return 1;
+ }
+ zid->saveRecord(&zr3);
+
+ // create a second record with peer ZID "210987654321"
+ ZIDRecord zr4((unsigned char*) "210987654321");
+ zid->getRecord(&zr4);
+ if (!zr4.isValid()) {
+ cerr << "New ZID record '210987654321' not set to valid" << endl;
+ return 1;
+ }
+ zid->saveRecord(&zr4);
+
+ // now set a first RS1 with default expiration interval, check
+ // if set correctly, valid flag and expiration interval
+ zr3.setNewRs1((unsigned char*) "11122233344455566677788899900012");
+ if (memcmp(zr3.getRs1(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+ cerr << "RS1 was not set (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs1Valid()) {
+ cerr << "RS1 was not set to valid state (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs1NotExpired()) {
+ cerr << "RS1 expired (111...012)" << endl;
+ return 1;
+ }
+ if (zr3.isRs2Valid()) {
+ cerr << "RS2 was set to valid state (111...012)" << endl;
+ return 1;
+ }
+ zid->saveRecord(&zr3);
+
+ // create a second RS1, RS2 will become the first RS1, check
+ // if set correctly, valid flag and expiration interval for both
+ // RS1 and RS2
+ zr3.setNewRs1((unsigned char*) "00099988877766655544433322211121");
+ if (memcmp(zr3.getRs1(), "00099988877766655544433322211121", RS_LENGTH) != 0) {
+ cerr << "RS1 was not set (000...121)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs1Valid()) {
+ cerr << "RS1 was not set to valid state (000...121)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs1NotExpired()) {
+ cerr << "RS1 expired (000...121)" << endl;
+ return 1;
+ }
+ if (memcmp(zr3.getRs2(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+ cerr << "RS2 was not set (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs2Valid()) {
+ cerr << "RS2 was not set to valid state (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3.isRs2NotExpired()) {
+ cerr << "RS2 expired (111...012)" << endl;
+ return 1;
+ }
+ zid->saveRecord(&zr3);
+
+ zid->close();
+
+ // Reopen, check if first record is still valid, RSx vaild and
+ // not expired. Then manipulate 2nd record.
+ zid->open("testzid2");
+
+ ZIDRecord zr3a((unsigned char*) "123456789012");
+ zid->getRecord(&zr3a);
+ if (!zr3a.isValid()) {
+ cerr << "Re-read ZID record '123456789012' not set to valid" << endl;
+ return 1;
+ }
+ if (memcmp(zr3a.getRs1(), "00099988877766655544433322211121", RS_LENGTH) != 0) {
+ cerr << "re-read RS1 was not set (000...121)" << endl;
+ return 1;
+ }
+ if (!zr3a.isRs1Valid()) {
+ cerr << "Re-read RS1 was not set to valid state (000...121)" << endl;
+ return 1;
+ }
+ if (!zr3a.isRs1NotExpired()) {
+ cerr << "re-read RS1 expired (000...121)" << endl;
+ return 1;
+ }
+ if (memcmp(zr3a.getRs2(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+ cerr << "re-read RS2 was not set (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3a.isRs2Valid()) {
+ cerr << "Re-read RS2 was not set to valid state (111...012)" << endl;
+ return 1;
+ }
+ if (!zr3a.isRs2NotExpired()) {
+ cerr << "Re-read RS2 expired (111...012)" << endl;
+ return 1;
+ }
+
+ ZIDRecord zr5((unsigned char*) "210987654321");
+ zid->getRecord(&zr5);
+
+
+ // set new RS1 with expire interval of 5 second, then check immediatly
+ zr5.setNewRs1((unsigned char*) "aaa22233344455566677788899900012", 5);
+ if (!zr5.isValid()) {
+ cerr << "Re-read ZID record '210987654321' not set to valid" << endl;
+ return 1;
+ }
+ if (memcmp(zr5.getRs1(), "aaa22233344455566677788899900012", RS_LENGTH) != 0) {
+ cerr << "RS1 (2) was not set (aaa...012)" << endl;
+ return 1;
+ }
+ if (!zr5.isRs1Valid()) {
+ cerr << "RS1 (2) was not set to valid state (aaa...012)" << endl;
+ return 1;
+ }
+ if (!zr5.isRs1NotExpired()) {
+ cerr << "RS1 (2) expired (aaa...012)" << endl;
+ return 1;
+ }
+
+ // wait for 6 second, now the expire check shall fail
+ sleep(6);
+ if (zr5.isRs1NotExpired()) {
+ cerr << "RS1 (2) is not expired after defined interval (aaa...012)" << endl;
+ return 1;
+ }
+
+ zr5.setNewRs1((unsigned char*) "bbb99988877766655544433322211121", 256);
+ zid->saveRecord(&zr5);
+
+ zid->close();
+
+ // Test migration
+ zid->open("testzidOld");
+ zid->close();
+
+}
+
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/src/ZIDRecord.cpp b/jni/libzrtp/sources/src/ZIDRecord.cpp
new file mode 100644
index 0000000..d62c2e3
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZIDRecord.cpp
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2006-2007 Werner Dittmann
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <time.h>
+
+#include <libzrtpcpp/ZIDRecord.h>
+
+void ZIDRecord::setNewRs1(const unsigned char* data, int32_t expire) {
+
+ // shift RS1 data into RS2 position
+ memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);
+ memcpy(record.rs2Interval, record.rs1Interval, TIME_LENGTH);
+
+ // now propagate flags as well
+ if (isRs1Valid()) {
+ setRs2Valid();
+ }
+
+ // set new RS1 data
+ memcpy(record.rs1Data, data, RS_LENGTH);
+
+ time_t validThru;
+ if (expire == -1) {
+ validThru = -1;
+ }
+ else if (expire <= 0) {
+ validThru = 0;
+ }
+ else {
+ validThru = time(NULL) + expire;
+ }
+
+ if (sizeof(time_t) == 4) {
+ long long temp = validThru;
+ memcpy(record.rs1Interval, (unsigned char*)&temp, TIME_LENGTH);
+ }
+ else {
+ memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);
+ }
+ setRs1Valid();
+}
+
+
+const bool ZIDRecord::isRs1NotExpired() {
+ time_t current = time(NULL);
+ time_t validThru;
+
+ if (sizeof(time_t) == 4) {
+ long long temp;
+ memcpy((unsigned char*)&temp, record.rs1Interval, TIME_LENGTH);
+ validThru = temp;
+ }
+ else {
+ memcpy((unsigned char*)&validThru, record.rs1Interval, TIME_LENGTH);
+ }
+
+ if (validThru == -1)
+ return true;
+ if (validThru == 0)
+ return false;
+ return (current <= validThru) ? true : false;
+}
+
+const bool ZIDRecord::isRs2NotExpired() {
+ time_t current = time(NULL);
+ time_t validThru;
+
+ if (sizeof(time_t) == 4) {
+ long long temp;
+ memcpy((unsigned char*)&temp, record.rs2Interval, TIME_LENGTH);
+ validThru = temp;
+ }
+ else {
+ memcpy((unsigned char*)&validThru, record.rs2Interval, TIME_LENGTH);
+ }
+
+ if (validThru == -1)
+ return true;
+ if (validThru == 0)
+ return false;
+ return (current <= validThru) ? true : false;
+}
+
+void ZIDRecord::setMiTMData(const unsigned char* data) {
+ memcpy(record.mitmKey, data, RS_LENGTH);
+ setMITMKeyAvailable();
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/ZRtp.cpp b/jni/libzrtp/sources/src/ZRtp.cpp
similarity index 69%
rename from jni/libzrtp/sources/zrtp/ZRtp.cpp
rename to jni/libzrtp/sources/src/ZRtp.cpp
index c7d2a46..50c29a9 100755
--- a/jni/libzrtp/sources/zrtp/ZRtp.cpp
+++ b/jni/libzrtp/sources/src/ZRtp.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -15,28 +15,23 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*F
* Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
*/
#include <sstream>
-#include <crypto/zrtpDH.h>
-#include <crypto/hmac256.h>
-#include <crypto/sha256.h>
-#include <crypto/hmac384.h>
-#include <crypto/sha384.h>
-
-#include <crypto/skeinMac256.h>
-#include <crypto/skein256.h>
-#include <crypto/skeinMac384.h>
-#include <crypto/skein384.h>
-
-#include <crypto/aesCFB.h>
-#include <crypto/twoCFB.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/crypto/hmac256.h>
+#include <libzrtpcpp/crypto/sha256.h>
+#include <libzrtpcpp/crypto/hmac384.h>
+#include <libzrtpcpp/crypto/sha384.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/twoCFB.h>
#include <libzrtpcpp/ZRtp.h>
#include <libzrtpcpp/ZrtpStateClass.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDFile.h>
+#include <libzrtpcpp/ZIDRecord.h>
#include <libzrtpcpp/Base32.h>
using namespace GnuZrtpCodes;
@@ -58,7 +53,7 @@
}
fprintf(stderr, "\n");
}
- * */
+ */
/*
* This method simplifies detection of libzrtpcpp inside Automake, configure
@@ -77,12 +72,10 @@
ZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb, std::string id, ZrtpConfigure* config, bool mitmm, bool sasSignSupport):
callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),
- rs2Valid(false), msgShaContext(NULL), hash(NULL), cipher(NULL), pubKey(NULL), sasType(NULL), authLength(NULL),
- multiStream(false), multiStreamAvailable(false), peerIsEnrolled(false), mitmSeen(false), pbxSecretTmp(NULL),
- enrollmentMode(false), configureAlgos(*config), zidRec(NULL), saveZidRecord(true) {
+ rs2Valid(false), msgShaContext(NULL), multiStream(false), multiStreamAvailable(false), pbxSecretTmp(NULL),
+ configureAlgos(*config) {
enableMitmEnrollment = config->isTrustedMitM();
- signatureData = NULL;
paranoidMode = config->isParanoidMode();
// setup the implicit hash function pointers and length
@@ -93,8 +86,6 @@
hmacFunctionImpl = hmac_sha256;
hmacListFunctionImpl = hmac_sha256;
- memcpy(ownZid, myZid, ZID_SIZE); // save the ZID
-
/*
* Generate H0 as a random number (256 bits, 32 bytes) and then
* the hash chain, refer to chapter 9. Use the implicit hash function.
@@ -104,39 +95,19 @@
sha256(H1, HASH_IMAGE_SIZE, H2); // H2
sha256(H2, HASH_IMAGE_SIZE, H3); // H3
- // configure all supported Hello packet versions
- zrtpHello_11.configureHello(&configureAlgos);
- zrtpHello_11.setH3(H3); // set H3 in Hello, included in helloHash
- zrtpHello_11.setZid(ownZid);
- zrtpHello_11.setVersion((uint8_t*)zrtpVersion_11);
+ zrtpHello.configureHello(&configureAlgos);
+ zrtpHello.setH3(H3); // set H3 in Hello, included in helloHash
+ memcpy(zid, myZid, ZID_SIZE);
+ zrtpHello.setZid(zid);
- zrtpHello_12.configureHello(&configureAlgos);
- zrtpHello_12.setH3(H3); // set H3 in Hello, included in helloHash
- zrtpHello_12.setZid(ownZid);
- zrtpHello_12.setVersion((uint8_t*)zrtpVersion_12);
+ if (mitmm) // this session acts for a trusted MitM (PBX)
+ zrtpHello.setMitmMode();
- if (mitmm) { // this session acts for a trusted MitM (PBX)
- zrtpHello_11.setMitmMode();
- zrtpHello_12.setMitmMode();
- }
- if (sasSignSupport) { // the application supports SAS signing
- zrtpHello_11.setSasSign();
- zrtpHello_12.setSasSign();
- }
+ if (sasSignSupport) // the application supports SAS signing
+ zrtpHello.setSasSign();
- // Keep array in ascending order (greater index -> greater version)
- helloPackets[0].packet = &zrtpHello_11;
- helloPackets[0].version = zrtpHello_11.getVersionInt();
- setClientId(id, &helloPackets[0]); // set id, compute HMAC and final helloHash
-
- helloPackets[1].packet = &zrtpHello_12;
- helloPackets[1].version = zrtpHello_12.getVersionInt();
- setClientId(id, &helloPackets[1]); // set id, compute HMAC and final helloHash
-
- currentHelloPacket = helloPackets[SUPPORTED_ZRTP_VERSIONS-1].packet; // start with highest supported version
- helloPackets[SUPPORTED_ZRTP_VERSIONS].packet = NULL;
- peerHelloVersion[0] = 0;
+ setClientId(id); // set id, compute HMAC and final helloHash
stateEngine = new ZrtpStateClass(this);
}
@@ -164,10 +135,6 @@
auxSecret = NULL;
auxSecretLength = 0;
}
- if (zidRec != NULL) {
- delete zidRec;
- zidRec = NULL;
- }
memset(hmacKeyI, 0, MAX_DIGEST_LENGTH);
memset(hmacKeyR, 0, MAX_DIGEST_LENGTH);
@@ -187,12 +154,11 @@
memset(zrtpSession, 0, MAX_DIGEST_LENGTH);
}
-void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC, size_t length) {
+void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC) {
Event_t ev;
peerSSRC = pSSRC;
ev.type = ZrtpPacket;
- ev.length = length;
ev.packet = message;
if (stateEngine != NULL) {
@@ -263,7 +229,7 @@
}
ZrtpPacketHello* ZRtp::prepareHello() {
- return currentHelloPacket;
+ return &zrtpHello;
}
ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
@@ -277,33 +243,20 @@
*/
ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
- myRole = Initiator;
+ sendInfo(Info, InfoHelloReceived);
- if (!hello->isLengthOk()) {
- *errMsg = CriticalSWError;
+ if (memcmp(hello->getVersion(), zrtpVersion, ZRTP_WORD_SIZE-1) != 0) {
+ *errMsg = UnsuppZRTPVersion;
return NULL;
}
- // Save data before detailed checks - may aid in analysing problems
- peerClientId.assign((char*)hello->getClientId(), ZRTP_WORD_SIZE * 4);
- memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
- peerHelloVersion[ZRTP_WORD_SIZE] = 0;
-
// Save our peer's (presumably the Responder) ZRTP id
memcpy(peerZid, hello->getZid(), ZID_SIZE);
- if (memcmp(peerZid, ownZid, ZID_SIZE) == 0) { // peers have same ZID????
+ if (memcmp(peerZid, zid, ZID_SIZE) == 0) { // peers have same ZID????
*errMsg = EqualZIDHello;
return NULL;
}
memcpy(peerH3, hello->getH3(), HASH_IMAGE_SIZE);
- int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
-
- // calculate hash over the received Hello packet - is peer's hello hash.
- // Use implicit hash algorithm
- hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
-
- sendInfo(Info, InfoHelloReceived);
-
/*
* The Following section extracts the algorithm from the peer's Hello
* packet. Always the preferend offered algorithms are
@@ -320,15 +273,10 @@
sasType = findBestSASType(hello);
if (!multiStream) {
- pubKey = findBestPubkey(hello); // Check for public key algorithm first, must set 'hash' as well
- if (hash == NULL) {
- *errMsg = UnsuppHashType;
- return NULL;
- }
- if (cipher == NULL) // public key selection may have set the cipher already
- cipher = findBestCipher(hello, pubKey);
- if (authLength == NULL) // public key selection may have set the SRTP authLen already
- authLength = findBestAuthLen(hello);
+ authLength = findBestAuthLen(hello);
+ pubKey = findBestPubkey(hello);
+ cipher = findBestCipher(hello, pubKey);
+ hash = findBestHash(hello);
multiStreamAvailable = checkMultiStream(hello);
}
else {
@@ -358,16 +306,22 @@
/*
* Prepare our DHPart2 packet here. Required to compute HVI. If we stay
* in Initiator role then we reuse this packet later in prepareDHPart2().
- * To create this DH packet we have to compute the retained secret ids,
- * thus get our peer's retained secret data first.
+ * To create this DH packet we have to compute the retained secret ids
+ * first. Thus get our peer's retained secret data first.
*/
- zidRec = getZidCacheInstance()->getRecord(peerZid);
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zidFile = ZIDFile::getInstance();
+ zidFile->getRecord(&zidRec);
//Compute the Initator's and Responder's retained secret ids.
computeSharedSecretSet(zidRec);
// Check if a PBX application set the MitM flag.
- mitmSeen = hello->isMitmMode();
+ if (hello->isMitmMode()) {
+ mitmSeen = true;
+ }
+ // Flag to record that fact that we have a MitM key of the other peer.
+ peerIsEnrolled = zidRec.isMITMKeyAvailable();
signSasSeen = hello->isSasSign();
// Construct a DHPart2 message (Initiator's DH message). This packet
@@ -397,7 +351,7 @@
// Compute the HVI, refer to chapter 5.4.1.1 of the specification
computeHvi(&zrtpDH2, hello);
- zrtpCommit.setZid(ownZid);
+ zrtpCommit.setZid(zid);
zrtpCommit.setHashType((uint8_t*)hash->getName());
zrtpCommit.setCipherType((uint8_t*)cipher->getName());
zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
@@ -417,6 +371,7 @@
// hash first messages to produce overall message hash
// First the Responder's Hello message, second the Commit (always Initator's).
// Must use negotiated hash.
+ int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
msgShaContext = createHashCtx();
hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
@@ -425,6 +380,12 @@
// Responder or DHPart1 as Initiator
storeMsgTemp(hello);
+ // calculate hash over the received Hello packet - is peer's hello hash.
+ // Use implicit hash algorithm
+ hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
+ memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
+ peerHelloVersion[ZRTP_WORD_SIZE] = 0;
+
return &zrtpCommit;
}
@@ -432,11 +393,11 @@
randomZRTP(hvi, ZRTP_WORD_SIZE*4); // This is the Multi-Stream NONCE size
- zrtpCommit.setZid(ownZid);
+ zrtpCommit.setZid(zid);
zrtpCommit.setHashType((uint8_t*)hash->getName());
zrtpCommit.setCipherType((uint8_t*)cipher->getName());
zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
- zrtpCommit.setPubKeyType((uint8_t*)mult); // this is fixed because of Multi Stream mode
+ zrtpCommit.setPubKeyType((uint8_t*)"Mult"); // this is fixed because of Multi Stream mode
zrtpCommit.setSasType((uint8_t*)sasType->getName());
zrtpCommit.setNonce(hvi);
zrtpCommit.setH2(H2);
@@ -466,11 +427,17 @@
// Responder or DHPart1 as Initiator
storeMsgTemp(hello);
+ // calculate hash over the received Hello packet - is peer's hello hash.
+ // Use implicit hash algorithm
+ hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
+ memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
+ peerHelloVersion[ZRTP_WORD_SIZE] = 0;
+
return &zrtpCommit;
}
/*
- * At this point we will take the role of the Responder. We have been in
+ * At this point we will take the role of the Responder. We may have been in
* the role of the Initiator before and already sent a commit packet that
* clashed with a commit packet from our peer. If our HVI was lower than our
* peer's HVI then we switched to Responder and handle our peer's commit packet
@@ -482,21 +449,8 @@
sendInfo(Info, InfoRespCommitReceived);
- if (!commit->isLengthOk(ZrtpPacketCommit::DhExchange)) {
- *errMsg = CriticalSWError;
- return NULL;
- }
-
- // Check if ZID in Commit is the same as we got in Hello
- uint8_t tmpZid[ZID_SIZE];
- memcpy(tmpZid, commit->getZid(), ZID_SIZE);
- if (memcmp(peerZid, tmpZid, ZID_SIZE) != 0) { // ZIDs do not match????
- sendInfo(Severe, SevereProtocolError);
- *errMsg = CriticalSWError;
- return NULL;
- }
-
- // The following code checks the hash chain according chapter 10 to detect false ZRTP packets.
+ // The following code check the hash chain according chapter 10 to detect
+ // false ZRTP packets.
// Must use the implicit hash function.
uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
@@ -544,22 +498,22 @@
if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
hash = cp;
setNegotiatedHash(hash);
+
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zidFile = ZIDFile::getInstance();
+ zidFile->getRecord(&zidRec);
+
// Compute the Initator's and Responder's retained secret ids
// with the committed hash.
computeSharedSecretSet(zidRec);
}
+
// check if we support the commited pub key type
cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
if (!cp->isValid()) { // no match - something went wrong
*errMsg = UnsuppPKExchange;
return NULL;
}
- if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38 || *(int32_t*)(cp->getName()) == *(int32_t*)e414) {
- if (!(*(int32_t*)(hash->getName()) == *(int32_t*)s384 || *(int32_t*)(hash->getName()) == *(int32_t*)skn3)) {
- *errMsg = UnsuppHashType;
- return NULL;
- }
- }
pubKey = cp;
// check if we support the commited SAS type
@@ -571,7 +525,7 @@
sasType = cp;
// dhContext cannot be NULL - always setup during prepareCommit()
- // check if we can use the dhContext prepared by prepareCommit(),
+ // check if we can use the dhContext prepared by prepareCOmmit(),
// if not delete old DH context and generate new one
// The algorithm names are 4 chars only, thus we can cast to int32_t
if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {
@@ -583,11 +537,7 @@
dhContext->getPubKeyBytes(pubKeyBytes);
- // Re-compute auxSecretIDr because we changed roles *IDr with my H3, *IDi with peer's H3
// Setup a DHPart1 packet.
- myRole = Responder;
- computeAuxSecretIds(); // recompute AUX secret ids because we are now Responder, use different H3
-
zrtpDH1.setPubKeyType(pubKey->getName());
zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);
zrtpDH1.setRs1Id(rs1IDr);
@@ -608,20 +558,22 @@
zrtpDH1.setHMAC(hmac);
// We are definitly responder. Save the peer's hvi for later compare.
+ myRole = Responder;
memcpy(peerHvi, commit->getHvi(), HVI_SIZE);
- // We are responder. Release the pre-computed SHA context because it was prepared for Initiator.
- // Setup and compute for Responder.
+ // We are responder. Release a possibly pre-computed SHA context
+ // because this was prepared for Initiator. Then create a new one.
if (msgShaContext != NULL) {
closeHashCtx(msgShaContext, NULL);
}
msgShaContext = createHashCtx();
// Hash messages to produce overall message hash:
- // First the Responder's (my) Hello message, second the Commit (always Initator's),
- // then the DH1 message (which is always a Responder's message).
- // Must use negotiated hash.
- hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+ // First the Responder's (my) Hello message, second the Commit
+ // (always Initator's), then the DH1 message (which is always a
+ // Responder's message).
+ // Must use negotiated hash
+ hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);
@@ -640,10 +592,6 @@
sendInfo(Info, InfoInitDH1Received);
- if (!dhPart1->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
// Because we are initiator the protocol engine didn't receive Commit
// thus could not store a peer's H2. A two step SHA256 is required to
// re-compute H3. Then compare with peer's H3 from peer's Hello packet.
@@ -682,6 +630,8 @@
}
dhContext->computeSecretKey(pvr, DHss);
+ myRole = Initiator;
+
// We are Initiator: the Responder's Hello and the Initiator's (our) Commit
// are already hashed in the context. Now hash the Responder's DH1 and then
// the Initiator's (our) DH2 in that order.
@@ -692,9 +642,17 @@
// Compute the message Hash
closeHashCtx(msgShaContext, messageHash);
msgShaContext = NULL;
+
+ // To compute the keys for the Initiator we need the retained secrets of our
+ // peer. Get them from the storage.
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
// Now compute the S0, all dependend keys and the new RS1. The function
// also performs sign SAS callback if it's active.
generateKeysInitiator(dhPart1, zidRec);
+ zid->saveRecord(&zidRec);
delete dhContext;
dhContext = NULL;
@@ -714,10 +672,6 @@
sendInfo(Info, InfoRespDH2Received);
- if (!dhPart2->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
// Because we are responder we received a Commit and stored its H2.
// Now re-compute H2 from received H1 and compare with stored peer's H2.
// Use implicit hash function
@@ -740,7 +694,7 @@
// using my Hello packet and the Initiator's DHPart2 and compare with
// hvi sent in commit packet. If it doesn't macht then a MitM attack
// may have occured.
- computeHvi(dhPart2, currentHelloPacket);
+ computeHvi(dhPart2, &zrtpHello);
if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
*errMsg = DHErrorWrongHVI;
return NULL;
@@ -757,20 +711,27 @@
return NULL;
}
dhContext->computeSecretKey(pvi, DHss);
-
- // Hash the Initiator's DH2 into the message Hash (other messages already prepared, see method prepareDHPart1().
+ // Hash the Initiator's DH2 into the message Hash (other messages already
+ // prepared, see method prepareDHPart1().
// Use neotiated hash function
hashCtxFunction(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(), dhPart2->getLength() * ZRTP_WORD_SIZE);
closeHashCtx(msgShaContext, messageHash);
msgShaContext = NULL;
+
+ // To compute the Keys for the Initiator we need the retained secrets of our
+ // peer. Get them from the storage.
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
/*
* The expected shared secret Ids were already computed when we built the
* DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
- * for the ZID record. The functions also performs sign SAS callback if it's
- * active. May reset the verify flag in ZID record.
+ * for the ZID record. The functions also performs sign SAS callback if it's active.
*/
generateKeysResponder(dhPart2, zidRec);
+ zid->saveRecord(&zidRec);
delete dhContext;
dhContext = NULL;
@@ -780,24 +741,19 @@
// Check if user verfied the SAS in a previous call and thus verfied
// the retained secret. Don't set the verified flag if paranoidMode is true.
- if (zidRec->isSasVerified() && !paranoidMode) {
+ if (zidRec.isSasVerified() && !paranoidMode) {
zrtpConfirm1.setSASFlag();
}
zrtpConfirm1.setExpTime(0xFFFFFFFF);
zrtpConfirm1.setIv(randomIV);
zrtpConfirm1.setHashH0(H0);
- // if this runs at PBX user agent enrollment service then set flag in confirm
+ // if this run at PBX user agent enrollment service then set flag in confirm
// packet and store the MitM key
if (enrollmentMode) {
- // As clarification to RFC6189: store new PBX secret only if we don't have
- // a matching PBX secret for the peer's ZID.
- if (!peerIsEnrolled) {
- computePBXSecret();
- zidRec->setMiTMData(pbxSecretTmp);
- }
- // Set flag to enable user's client to ask for confirmation or re-confirmation.
+ computePBXSecret();
zrtpConfirm1.setPBXEnrollment();
+ writeEnrollmentPBX();
}
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -821,10 +777,6 @@
sendInfo(Info, InfoRespCommitReceived);
- if (!commit->isLengthOk(ZrtpPacketCommit::MultiStream)) {
- *errMsg = CriticalSWError;
- return NULL;
- }
// The following code checks the hash chain according chapter 10 to detect
// false ZRTP packets.
// Use implicit hash function
@@ -895,7 +847,7 @@
// First the Responder's (my) Hello message, second the Commit
// (always Initator's)
// use negotiated hash
- hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+ hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
closeHashCtx(msgShaContext, messageHash);
@@ -933,10 +885,6 @@
sendInfo(Info, InfoInitConf1Received);
- if (!confirm1->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -951,7 +899,10 @@
*errMsg = ConfirmHMACWrong;
return NULL;
}
- cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
+ cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
+
+ std::string cs(cipher->getReadable());
+ cs.append("/").append(pubKey->getName());
// Check HMAC of DHPart1 packet stored in temporary buffer. The
// HMAC key of the DHPart1 packet is peer's H0 that is contained in
@@ -962,7 +913,7 @@
return NULL;
}
signatureLength = confirm1->getSignatureLength();
- if (signSasSeen && signatureLength > 0 && confirm1->isSignatureLengthOk()) {
+ if (signSasSeen && signatureLength > 0) {
signatureData = confirm1->getSignatureData();
callback->checkSASSignature(sasHash);
// TODO: error handling if checkSASSignature returns false.
@@ -973,18 +924,27 @@
*/
bool sasFlag = confirm1->isSASFlag();
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+
+ ZIDFile *zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
// Our peer did not confirm the SAS in last session, thus reset
// our SAS flag too. Reset the flag also if paranoidMode is true.
if (!sasFlag || paranoidMode) {
- zidRec->resetSasVerified();
+ zidRec.resetSasVerified();
}
// get verified flag from current RS1 before set a new RS1. This
// may not be set even if peer's flag is set in confirm1 message.
- sasFlag = zidRec->isSasVerified();
+ sasFlag = zidRec.isSasVerified();
+
+ callback->srtpSecretsOn(cs, SAS, sasFlag);
// now we are ready to save the new RS1 which inherits the verified
// flag from old RS1
- zidRec->setNewRs1((const uint8_t*)newRs1);
+ zidRec.setNewRs1((const uint8_t*)newRs1);
+ zid->saveRecord(&zidRec);
// now generate my Confirm2 message
zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
@@ -1005,19 +965,10 @@
// packet and store the MitM key. The PBX user agent service always stores
// its MitM key.
if (enrollmentMode) {
- // As clarification to RFC6189: store new PBX secret only if we don't have
- // a matching PBX secret for the peer's ZID.
- if (!peerIsEnrolled) {
- computePBXSecret();
- zidRec->setMiTMData(pbxSecretTmp);
- }
- // Set flag to enable user's client to ask for confirmation or re-confirmation.
zrtpConfirm2.setPBXEnrollment();
+ writeEnrollmentPBX();
}
}
- if (saveZidRecord)
- getZidCacheInstance()->saveRecord(zidRec);
-
// Encrypt and HMAC with Initiator's key - we are Initiator here
hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
@@ -1032,18 +983,27 @@
// agent stores the MitM key only if the user accepts the enrollment
// request.
if (enableMitmEnrollment && confirm1->isPBXEnrollment()) {
- // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
- // ask for reconfirmation.
- if (!peerIsEnrolled) {
- callback->zrtpAskEnrollment(EnrollmentRequest);
- }
- else {
- callback->zrtpAskEnrollment(EnrollmentReconfirm);
- }
+ callback->zrtpAskEnrollment(EnrollmentRequest);
}
return &zrtpConfirm2;
}
+/**
+ * Save the computed MitM secret to the ZID record of the peer
+ */
+void ZRtp::writeEnrollmentPBX() {
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+
+ ZIDFile *zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
+ if (pbxSecretTmp != NULL) {
+ zidRec.setMiTMData(pbxSecretTmp);
+ }
+ zid->saveRecord(&zidRec);
+}
+
/*
* At this point we are Initiator.
*/
@@ -1054,10 +1014,6 @@
// don't update SAS, RS
sendInfo(Info, InfoInitConf1Received);
- if (!confirm1->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -1078,8 +1034,8 @@
*errMsg = ConfirmHMACWrong;
return NULL;
}
- // Cast away the const for the IV - the standalone AES CFB modifies IV on return
- cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
+ cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
+ std::string cs(cipher->getReadable());
// Because we are initiator the protocol engine didn't receive Commit and
// because we are using multi-stream mode here we also did not receive a DHPart1 and
@@ -1099,6 +1055,12 @@
*errMsg = CriticalSWError;
return NULL;
}
+ // TODO: here we have a SAS signature from reponder, call checkSASsignature (save / compare in case of resend)
+
+ // Inform GUI about security state, don't show SAS and its state
+ std::string cs1("");
+ callback->srtpSecretsOn(cs, cs1, true);
+
// now generate my Confirm2 message
zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
zrtpConfirm2.setHashH0(H0);
@@ -1123,10 +1085,6 @@
sendInfo(Info, InfoRespConf2Received);
- if (!confirm2->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -1143,8 +1101,9 @@
*errMsg = ConfirmHMACWrong;
return NULL;
}
- // Cast away the const for the IV - the standalone AES CFB modifies IV on return
- cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), (uint8_t*)confirm2->getIv(), confirm2->getHashH0(), hmlen);
+ cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), confirm2->getIv(), confirm2->getHashH0(), hmlen);
+
+ std::string cs(cipher->getReadable());
if (!multiStream) {
// Check HMAC of DHPart2 packet stored in temporary buffer. The
@@ -1156,7 +1115,7 @@
return NULL;
}
signatureLength = confirm2->getSignatureLength();
- if (signSasSeen && signatureLength > 0 && confirm2->isSignatureLengthOk() ) {
+ if (signSasSeen && signatureLength > 0) {
signatureData = confirm2->getSignatureData();
callback->checkSASSignature(sasHash);
// TODO: error handling if checkSASSignature returns false.
@@ -1166,16 +1125,29 @@
* GUI about state.
*/
bool sasFlag = confirm2->isSASFlag();
+
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+
+ ZIDFile *zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
// Our peer did not confirm the SAS in last session, thus reset
// our SAS flag too. Reset the flag also if paranoidMode is true.
if (!sasFlag || paranoidMode) {
- zidRec->resetSasVerified();
+ zidRec.resetSasVerified();
}
+ // Now get the resulting SAS verified flag from current RS1 before setting a new RS1.
+ // It's a combination of our SAS verfied flag and peer's verified flag. Only if both
+ // were set (true) then sasFlag becomes true.
+ sasFlag = zidRec.isSasVerified();
+ cs.append("/").append(pubKey->getName());
+ callback->srtpSecretsOn(cs, SAS, sasFlag);
+
// save new RS1, this inherits the verified flag from old RS1
- zidRec->setNewRs1((const uint8_t*)newRs1);
- if (saveZidRecord)
- getZidCacheInstance()->saveRecord(zidRec);
+ zidRec.setNewRs1((const uint8_t*)newRs1);
+ zid->saveRecord(&zidRec);
// Ask for enrollment only if enabled via configuration and the
// confirm packet contains the enrollment flag. The enrolling user
@@ -1183,14 +1155,7 @@
// request.
if (enableMitmEnrollment && confirm2->isPBXEnrollment()) {
computePBXSecret();
- // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
- // ask for reconfirmation.
- if (!peerIsEnrolled) {
- callback->zrtpAskEnrollment(EnrollmentRequest);
- }
- else {
- callback->zrtpAskEnrollment(EnrollmentReconfirm);
- }
+ callback->zrtpAskEnrollment(EnrollmentRequest);
}
}
else {
@@ -1205,15 +1170,16 @@
*errMsg = CriticalSWError;
return NULL;
}
+ std::string cs1("");
+
+ // Inform GUI about security state, don't show SAS and its state
+ callback->srtpSecretsOn(cs, cs1, true);
}
return &zrtpConf2Ack;
}
ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
- if (epkt->getLength() < 4)
- sendInfo(ZrtpError, CriticalSWError * -1);
- else
- sendInfo(ZrtpError, epkt->getErrorCode() * -1);
+ sendInfo(ZrtpError, epkt->getErrorCode() * -1);
return &zrtpErrorAck;
}
@@ -1223,12 +1189,11 @@
}
ZrtpPacketPingAck* ZRtp::preparePingAck(ZrtpPacketPing* ppkt) {
- if (ppkt->getLength() != 6) // A PING packet must have a length of 6 words
- return NULL;
+
// Because we do not support ZRTP proxy mode use the truncated ZID.
// If this code shall be used in ZRTP proxy implementation the computation
// of the endpoint hash must be enhanced (see chaps 5.15ff and 5.16)
- zrtpPingAck.setLocalEpHash(ownZid);
+ zrtpPingAck.setLocalEpHash(zid);
zrtpPingAck.setRemoteEpHash(ppkt->getEpHash());
zrtpPingAck.setSSRC(peerSSRC);
return &zrtpPingAck;
@@ -1240,10 +1205,6 @@
if (!mitmSeen || paranoidMode)
return &zrtpRelayAck;
- if (!srly->isLengthOk()) {
- *errMsg = CriticalSWError;
- return NULL;
- }
uint8_t* hkey, *ekey;
// If we are responder then the PBX used it's Initiator keys
if (myRole == Responder) {
@@ -1258,6 +1219,8 @@
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
+ // Use the Initiator's keys here because we are Responder here and
+ // reveice packets from Initiator
int16_t hmlen = (srly->getLength() - 9) * ZRTP_WORD_SIZE;
// Use negotiated HMAC (hash)
@@ -1267,10 +1230,11 @@
*errMsg = ConfirmHMACWrong;
return NULL; // TODO - check error handling
}
- // Cast away the const for the IV - the standalone AES CFB modifies IV on return
- cipher->getDecrypt()(ekey, cipher->getKeylen(), (uint8_t*)srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
+ cipher->getDecrypt()(ekey, cipher->getKeylen(), srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
+ const uint8_t* render = srly->getSas();
const uint8_t* newSasHash = srly->getTrustedSas();
+
bool sasHashNull = true;
for (int i = 0; i < HASH_IMAGE_SIZE; i++) {
if (newSasHash[i] != 0) {
@@ -1278,38 +1242,27 @@
break;
}
}
- std::string cs(cipher->getReadable());
- cs.append("/").append(pubKey->getName());
-
// Check if new SAS is null or a trusted MitM relationship doesn't exist.
// If this is the case then don't render and don't show the new SAS - use
- // our computed SAS hash but we may use a different SAS rendering algorithm to
+ // the computed SAS hash but we may use a different SAS rendering algorithm to
// render the computed SAS.
if (sasHashNull || !peerIsEnrolled) {
- cs.append("/MitM");
newSasHash = sasHash;
}
- else {
- cs.append("/SASviaMitM");
- }
// If other SAS schemes required - check here and use others
- const uint8_t* render = srly->getSasAlgo();
AlgorithmEnum* renderAlgo = &zrtpSasTypes.getByName((const char*)render);
- uint8_t sasBytes[4];
+ uint8_t sasBytes[4];;
if (renderAlgo->isValid()) {
sasBytes[0] = newSasHash[0];
sasBytes[1] = newSasHash[1];
sasBytes[2] = newSasHash[2] & 0xf0;
sasBytes[3] = 0;
- if (*(int32_t*)b32 == *(int32_t*)(renderAlgo->getName())) {
- SAS = Base32(sasBytes, 20).getEncoded();
- }
- else {
- SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
- }
}
- bool verify = zidRec->isSasVerified() && srly->isSASFlag();
- callback->srtpSecretsOn(cs, SAS, verify);
+ SAS = Base32(sasBytes, 20).getEncoded();
+ std::string cs(cipher->getReadable());
+ cs.append("/").append(pubKey->getName()).append("/MitM");
+
+ callback->srtpSecretsOn(cs, SAS, false);
return &zrtpRelayAck;
}
@@ -1359,26 +1312,42 @@
int numAlgosConf;
AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
+ bool mandatoryFound = false;
+
// If Hello does not contain any hash names return Sha256, its mandatory
int num = hello->getNumHashes();
if (num == 0) {
return &zrtpHashes.getByName(mandatoryHash);
}
- // Build list of configured hash algorithm names.
+ // Build list of configured hash algorithm names, append mandatory algos
+ // if necessary.
numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
+ if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryHash) {
+ mandatoryFound = true;
+ }
+ }
+ if (!mandatoryFound) {
+ algosConf[numAlgosConf++] = &zrtpHashes.getByName(mandatoryHash);
}
// Build list of offered known algos in Hello, append mandatory algos if necessary
+ mandatoryFound = false;
for (numAlgosOffered = 0, i = 0; i < num; i++) {
algosOffered[numAlgosOffered] = &zrtpHashes.getByName((const char*)hello->getHashType(i));
if (!algosOffered[numAlgosOffered]->isValid())
continue;
- numAlgosOffered++;
+ if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryHash) {
+ mandatoryFound = true;
+ }
+ }
+ if (!mandatoryFound) {
+ algosOffered[numAlgosOffered++] = &zrtpHashes.getByName(mandatoryHash);
}
- // Lookup offered algos in configured algos.
+ // Lookup offered algos in configured algos. Because of appended
+ // mandatory algorithms at least one match will happen
for (i = 0; i < numAlgosOffered; i++) {
for (ii = 0; ii < numAlgosConf; ii++) {
if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1389,7 +1358,6 @@
return &zrtpHashes.getByName(mandatoryHash);
}
-
AlgorithmEnum* ZRtp::findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk) {
int i;
@@ -1400,24 +1368,44 @@
int numAlgosConf;
AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
+ bool mandatoryFound = false;
+
int num = hello->getNumCiphers();
if (num == 0 || (*(int32_t*)(pk->getName()) == *(int32_t*)dh2k)) {
return &zrtpSymCiphers.getByName(aes1);
}
- // Build list of configured cipher algorithm names.
+ // Build list of configured cipher algorithm names, append mandatory algos
+ // if necessary.
numAlgosConf = configureAlgos.getNumConfiguredAlgos(CipherAlgorithm);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(CipherAlgorithm, i);
+ if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryCipher) {
+ mandatoryFound = true;
+ }
}
- // Build list of offered known algos names in Hello.
+ if (!mandatoryFound) {
+ algosConf[numAlgosConf++] = &zrtpSymCiphers.getByName(mandatoryCipher);
+ }
+
+ // Build list of offered known algos names in Hello, append mandatory algos if
+ // necessary
+ mandatoryFound = false;
for (numAlgosOffered = 0, i = 0; i < num; i++) {
algosOffered[numAlgosOffered] = &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
if (!algosOffered[numAlgosOffered]->isValid())
continue;
- numAlgosOffered++;
+ if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryCipher) {
+ mandatoryFound = true;
+ }
}
- // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
+
+ if (!mandatoryFound) {
+ algosOffered[numAlgosOffered++] = &zrtpSymCiphers.getByName(mandatoryCipher);
+ }
+
+ // Lookup offered algos in configured algos. Because of appended
+ // mandatory algorithms at least one match will happen
for (i = 0; i < numAlgosOffered; i++) {
for (ii = 0; ii < numAlgosConf; ii++) {
if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1425,106 +1413,70 @@
}
}
}
- // If we don't have a match - use the mandatory algorithm
return &zrtpSymCiphers.getByName(mandatoryCipher);
}
-// We can have the non-NIST in the list of orderedAlgos even if they are not available
-// in the code (refer to ZrtpConfigure.cpp). If they are not build in they cannot appear
-// in'configureAlgos' and thus not in the intersection lists. Thus a ZRTP build that
-// does not include the non-NIST curves also works without problems.
-//
AlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
- AlgorithmEnum* peerIntersect[ZrtpConfigure::maxNoOfAlgos+1];
- AlgorithmEnum* ownIntersect[ZrtpConfigure::maxNoOfAlgos+1];
+ int i;
+ int ii;
+ int numAlgosOffered;
+ AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
- // Build list of own pubkey algorithm names, must follow the order
- // defined in RFC 6189, chapter 4.1.2.
- const char *orderedAlgos[] = {dh2k, e255, ec25, dh3k, e414, ec38};
- int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);
+ int numAlgosConf;
+ AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
- int numAlgosPeer = hello->getNumPubKeys();
- if (numAlgosPeer == 0) {
- hash = findBestHash(hello); // find a hash algorithm
+ bool mandatoryFound = false;
+
+ int num = hello->getNumPubKeys();
+ if (num == 0) {
return &zrtpPubKeys.getByName(mandatoryPubKey);
}
- // Build own list of intersecting algos, keep own order or algorithms
- // The list must include real public key algorithms only, so skip mult-stream mode,
- // preshared and alike.
- int numAlgosOwn = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
- int numOwnIntersect = 0;
- for (int i = 0; i < numAlgosOwn; i++) {
- ownIntersect[numOwnIntersect] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, i);
- if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)mult) {
+ // Build list of configured pubkey algorithm names, append mandatory algos
+ // if necessary.
+ // The list must include real public key algorithms only, so skip
+ // mult-stream mode, preshared and alike.
+ numAlgosConf = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
+ for (i = 0, ii = 0; i < numAlgosConf; i++) {
+ algosConf[ii] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, ii);
+ if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)mult) {
continue; // skip multi-stream mode
}
- for (int ii = 0; ii < numAlgosPeer; ii++) {
- if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)(zrtpPubKeys.getByName((const char*)hello->getPubKeyType(ii)).getName())) {
- numOwnIntersect++;
- break;
+ if (*(int32_t*)(algosConf[ii++]->getName()) == *(int32_t*)mandatoryPubKey) {
+ mandatoryFound = true;
+ }
+ }
+
+ numAlgosConf = ii;
+ if (!mandatoryFound) {
+ algosConf[numAlgosConf++] = &zrtpPubKeys.getByName(mandatoryPubKey);
+ }
+
+ // Build list of offered known algos in Hello, append mandatory algos if necessary
+ mandatoryFound = false;
+ for (numAlgosOffered = 0, i = 0; i < num; i++) {
+ algosOffered[numAlgosOffered] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
+ if (!algosOffered[numAlgosOffered]->isValid())
+ continue;
+ if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryPubKey) {
+ mandatoryFound = true;
+ }
+ }
+
+ if (!mandatoryFound) {
+ algosOffered[numAlgosOffered++] = &zrtpPubKeys.getByName(mandatoryPubKey);
+ }
+
+ // Lookup offered algos in configured algos. Because of appended
+ // mandatory algorithms at least one match will happen
+ for (i = 0; i < numAlgosOffered; i++) {
+ for (ii = 0; ii < numAlgosConf; ii++) {
+ if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
+ return algosConf[ii];
}
}
}
- // Build list of peer's intersecting algos: take own list as input and build a
- // list of algorithms that we have in common. The order of the list is according
- // to peer's Hello packet (peer's preferences).
- int numPeerIntersect = 0;
- for (int i = 0; i < numAlgosPeer; i++) {
- peerIntersect[numPeerIntersect] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
- for (int ii = 0; ii < numOwnIntersect; ii++) {
- if (*(int32_t*)(ownIntersect[ii]->getName()) == *(int32_t*)(peerIntersect[numPeerIntersect]->getName())) {
- numPeerIntersect++;
- break;
- }
- }
- }
- if (numPeerIntersect == 0) { // If we don't have a common algorithm - use mandatory algorithms
- hash = findBestHash(hello);
- return &zrtpPubKeys.getByName(mandatoryPubKey);
- }
-
- // If we have only one algorithm in common or if the first entry matches - take it.
- // Otherwise determine which algorithm from the intersection lists is first in the
- // list of ordered algorithms and select it (RFC6189, section 4.1.2).
- AlgorithmEnum* useAlgo;
- if (numPeerIntersect > 1 && *(int32_t*)(ownIntersect[0]->getName()) != *(int32_t*)(peerIntersect[0]->getName())) {
- int own, peer;
-
- const int32_t *name = (int32_t*)ownIntersect[0]->getName();
- for (own = 0; own < numOrderedAlgos; own++) {
- if (*name == *(int32_t*)orderedAlgos[own])
- break;
- }
- name = (int32_t*)peerIntersect[0]->getName();
- for (peer = 0; peer < numOrderedAlgos; peer++) {
- if (*name == *(int32_t*)orderedAlgos[peer])
- break;
- }
- if (own < peer) {
- useAlgo = ownIntersect[0];
- }
- else {
- useAlgo = peerIntersect[0];
- }
- // find fastest of conf vs intersecting
- }
- else {
- useAlgo = peerIntersect[0];
- }
- int32_t algoName = *(int32_t*)(useAlgo->getName());
-
- // select a corresponding strong hash if necessary.
- if (algoName == *(int32_t*)ec38 || algoName == *(int32_t*)e414) {
- hash = getStrongHashOffered(hello, algoName);
- cipher = getStrongCipherOffered(hello, algoName);
- }
- else {
- hash = getHashOffered(hello, algoName);;
- cipher = getCipherOffered(hello, algoName);
- }
- authLength = getAuthLenOffered(hello, algoName);
- return useAlgo;
+ return &zrtpPubKeys.getByName(mandatoryPubKey);
}
AlgorithmEnum* ZRtp::findBestSASType(ZrtpPacketHello *hello) {
@@ -1537,23 +1489,42 @@
int numAlgosConf;
AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
+ bool mandatoryFound = false;
+
int num = hello->getNumSas();
if (num == 0) {
return &zrtpSasTypes.getByName(mandatorySasType);
}
- // Build list of configured SAS algorithm names
+ // Buildlist of configured SAS algorithm names, append mandatory algos
+ // if necessary.
numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);
+ if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatorySasType) {
+ mandatoryFound = true;
+ }
}
- // Build list of offered known algos in Hello,
+
+ if (!mandatoryFound) {
+ algosConf[numAlgosConf++] = &zrtpSasTypes.getByName(mandatorySasType);
+ }
+
+ // Build list of offered known algos in Hello, append mandatory algos if necessary
for (numAlgosOffered = 0, i = 0; i < num; i++) {
- algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i));
+ algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i++));
if (!algosOffered[numAlgosOffered]->isValid())
continue;
- numAlgosOffered++;
+ if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatorySasType) {
+ mandatoryFound = true;
+ }
}
- // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
+
+ if (!mandatoryFound) {
+ algosOffered[numAlgosOffered++] = &zrtpSasTypes.getByName(mandatorySasType);
+ }
+
+ // Lookup offered algos in configured algos. Because of appended
+ // mandatory algorithms at least one match will happen
for (i = 0; i < numAlgosOffered; i++) {
for (ii = 0; ii < numAlgosConf; ii++) {
if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1561,7 +1532,6 @@
}
}
}
- // If we don't have a match - use the mandatory algorithm
return &zrtpSasTypes.getByName(mandatorySasType);
}
@@ -1575,26 +1545,55 @@
int numAlgosConf;
AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+2];
+ bool mandatoryFound_1 = false;
+ bool mandatoryFound_2 = false;
+
int num = hello->getNumAuth();
if (num == 0) {
return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
}
- // Build list of configured Authentication tag length algorithm names.
+ // Build list of configured SAS algorithm names, append mandatory algos
+ // if necessary.
numAlgosConf = configureAlgos.getNumConfiguredAlgos(AuthLength);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(AuthLength, i);
+ if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
+ mandatoryFound_1 = true;
+ }
+ if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
+ mandatoryFound_2 = true;
+ }
}
- // Build list of offered known algos in Hello.
+ if (!mandatoryFound_1) {
+ algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
+ }
+
+ if (!mandatoryFound_2) {
+ algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
+ }
+
+ // Build list of offered known algos in Hello, append mandatory algos if necessary
for (numAlgosOffered = 0, i = 0; i < num; i++) {
algosOffered[numAlgosOffered] = &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
if (!algosOffered[numAlgosOffered]->isValid())
continue;
- numAlgosOffered++;
+ if (*(int32_t*)(algosOffered[numAlgosOffered]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
+ mandatoryFound_1 = true;
+ }
+ if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
+ mandatoryFound_2 = true;
+ }
}
-
- // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
+ if (!mandatoryFound_1) {
+ algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
+ }
+ if (!mandatoryFound_2) {
+ algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
+ }
+ // Lookup offered algos in configured algos. Because of appended
+ // mandatory algorithms at least one match will happen
for (i = 0; i < numAlgosOffered; i++) {
for (ii = 0; ii < numAlgosConf; ii++) {
if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1602,115 +1601,9 @@
}
}
}
- // If we don't have a match - use the mandatory algorithm
return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
}
-// The following set of functions implement a 'non-NIST first policy' if nonNist computes
-// to true. They prefer nonNist algorithms if these are available. Otherwise they use the NIST
-// counterpart or simply call the according findBest*(...) function.
-//
-// Only the findBestPubkey(...) function calls them after it selected the public key algorithm.
-// If the public key algorithm is non-NIST and if the policy is set to PreferNonNist then
-// nonNist becomes true.
-//
-// The functions work according to the RFC6189 spec: the initiator can select every algorithm
-// that both parties support. Thus the Initiator can even select an algorithm the wasn't offered
-// in its own Hello packet but that the Initiator found in the peer's Hello and that is available
-// for it.
-//
-AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
- int numHash = hello->getNumHashes();
- bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
- if (nonNist) {
- for (int i = 0; i < numHash; i++) {
- int32_t nm = *(int32_t*)(hello->getHashType(i));
- if (nm == *(int32_t*)skn3) {
- return &zrtpHashes.getByName((const char*)hello->getHashType(i));
- }
- }
- }
- for (int i = 0; i < numHash; i++) {
- int32_t nm = *(int32_t*)(hello->getHashType(i));
- if (nm == *(int32_t*)s384 || nm == *(int32_t*)skn3) {
- return &zrtpHashes.getByName((const char*)hello->getHashType(i));
- }
- }
- return NULL; // returning NULL -> prepareCommit(...) terminates ZRTP, missing strong hash is an error
-}
-
-AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
- int num = hello->getNumCiphers();
- bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
- if (nonNist) {
- for (int i = 0; i < num; i++) {
- int32_t nm = *(int32_t*)(hello->getCipherType(i));
- if (nm == *(int32_t*)two3) {
- return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
- }
- }
- }
- for (int i = 0; i < num; i++) {
- int32_t nm = *(int32_t*)(hello->getCipherType(i));
- if (nm == *(int32_t*)aes3 || nm == *(int32_t*)two3) {
- return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
- }
- }
- return NULL; // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
- int num = hello->getNumHashes();
- bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
- if (nonNist) {
- for (int i = 0; i < num; i++) {
- int32_t nm = *(int32_t*)(hello->getHashType(i));
- if (nm == *(int32_t*)skn2 || nm == *(int32_t*)skn3) {
- return &zrtpHashes.getByName((const char*)hello->getHashType(i));
- }
- }
- }
- return findBestHash(hello);
-}
-
-AlgorithmEnum* ZRtp::getCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
- int num = hello->getNumCiphers();
- bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
- if (nonNist) {
- for (int i = 0; i < num; i++) {
- int32_t nm = *(int32_t*)(hello->getCipherType(i));
- if (nm == *(int32_t*)two2 || nm == *(int32_t*)two3) {
- return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
- }
- }
- }
- return NULL; // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
- int num = hello->getNumAuth();
- bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
- if (nonNist) {
- for (int i = 0; i < num; i++) {
- int32_t nm = *(int32_t*)(hello->getAuthLen(i));
- if (nm == *(int32_t*)sk32 || nm == *(int32_t*)sk64) {
- return &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
- }
- }
- }
- return findBestAuthLen(hello);
-}
-
bool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {
int i;
@@ -1731,10 +1624,6 @@
bool ZRtp::verifyH2(ZrtpPacketCommit *commit) {
uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
- // packet does not have the correct size, treat H2 verfication as failed.
- if (!commit->isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange))
- return false;
-
sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);
if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
return false;
@@ -1761,7 +1650,7 @@
return;
}
-void ZRtp:: computeSharedSecretSet(ZIDRecord *zidRec) {
+void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
/*
* Compute the Initiator's and Reponder's retained shared secret Ids.
@@ -1770,64 +1659,45 @@
uint8_t randBuf[RS_LENGTH];
uint32_t macLen;
- fprintf(stderr, "Compute shared secrets\n");
- detailInfo.secretsCached = 0;
- if (!zidRec->isRs1Valid()) {
+ if (!zidRec.isRs1Valid()) {
randomZRTP(randBuf, RS_LENGTH);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
}
else {
rs1Valid = true;
- hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
- hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
- detailInfo.secretsCached = Rs1;
+ hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
+ hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
}
- if (!zidRec->isRs2Valid()) {
+ if (!zidRec.isRs2Valid()) {
randomZRTP(randBuf, RS_LENGTH);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
}
else {
rs2Valid = true;
- hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
- hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
- detailInfo.secretsCached |= Rs2;
+ hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
+ hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
}
- if (!zidRec->isMITMKeyAvailable()) {
+ /*
+ * For the time being we don't support this types of shared secrect. Could be
+ * easily done: somebody sets some data into our ZRtp object, check it here
+ * and use it. Otherwise use the random data.
+ */
+ randomZRTP(randBuf, RS_LENGTH);
+ hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), auxSecretIDi, &macLen);
+ hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), auxSecretIDr, &macLen);
+
+ if (!zidRec.isMITMKeyAvailable()) {
randomZRTP(randBuf, RS_LENGTH);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
-
}
else {
- hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
- hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
- detailInfo.secretsCached |= Pbx;
- }
- computeAuxSecretIds();
-}
-
-void ZRtp::computeAuxSecretIds() {
- uint8_t randBuf[RS_LENGTH];
- uint32_t macLen;
-
- if (auxSecret == NULL) {
- randomZRTP(randBuf, RS_LENGTH);
- hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
- hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
- }
- else {
- if (myRole == Initiator) { // I'm initiator thus use my H3 for initiator's IDi, peerH3 for respnder's IDr
- hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
- hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
- }
- else {
- hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
- hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
- }
+ hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
+ hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
}
}
@@ -1837,70 +1707,49 @@
* to chapter 5.3 in the specification).
* When using this method then we are in Initiator role.
*/
-void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
+void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
const uint8_t* setD[3];
int32_t rsFound = 0;
setD[0] = setD[1] = setD[2] = NULL;
- detailInfo.secretsMatchedDH = 0;
- if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
- detailInfo.secretsMatchedDH |= Rs1;
- if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
- detailInfo.secretsMatchedDH |= Rs2;
/*
* Select the real secrets into setD. The dhPart is DHpart1 message
* received from responder. rs1IDr and rs2IDr are the expected ids using
* the initator's cached retained secrets.
*/
- // Check which RS we shall use for first place (s1)
- detailInfo.secretsMatched = 0;
+ int matchingSecrets = 0;
if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs1();
+ setD[matchingSecrets++] = zidRec.getRs1();
rsFound = 0x1;
- detailInfo.secretsMatched = Rs1;
}
else if (memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs1();
+ setD[matchingSecrets++] = zidRec.getRs1();
rsFound = 0x2;
- detailInfo.secretsMatched = Rs1;
}
else if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs2();
+ setD[matchingSecrets++] = zidRec.getRs2();
rsFound = 0x4;
- detailInfo.secretsMatched = Rs2;
}
else if (memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs2();
+ setD[matchingSecrets++] = zidRec.getRs2();
rsFound = 0x8;
- detailInfo.secretsMatched = Rs2;
}
-
+ /* *** Not yet supported
if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
- DEBUGOUT((fprintf(stdout, "Initiator: Match for aux secret found\n")));
- setD[1] = auxSecret;
- detailInfo.secretsMatched |= Aux;
- detailInfo.secretsMatchedDH |= Aux;
+ DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
+ setD[matchingSecrets++] = auxSecret;
}
- if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {
- sendInfo(Warning, WarningNoExpectedAuxMatch);
- }
-
- // check if we have a matching PBX secret and place it third (s3)
- if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), HMAC_SIZE) == 0) {
+ */
+ if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), 8) == 0) {
DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
- setD[2] = zidRec->getMiTMData();
- detailInfo.secretsMatched |= Pbx;
- detailInfo.secretsMatchedDH |= Pbx;
- // Flag to record that fact that we have a MitM key of the other peer.
- peerIsEnrolled = true;
+ setD[matchingSecrets++] = zidRec.getMiTMData();
}
// Check if some retained secrets found
if (rsFound == 0) { // no RS matches found
if (rs1Valid || rs2Valid) { // but valid RS records in cache
sendInfo(Warning, WarningNoExpectedRSMatch);
- zidRec->resetSasVerified();
- saveZidRecord = false; // Don't save RS until user verfied/confirmed SAS
+ zidRec.resetSasVerified();
}
else { // No valid RS record in cache
sendInfo(Warning, WarningNoRSMatch);
@@ -1934,7 +1783,7 @@
//Very first element is a fixed counter, big endian
counter = 1;
- counter = zrtpHtonl(counter);
+ counter = htonl(counter);
data[pos] = (unsigned char*)&counter;
length[pos++] = sizeof(uint32_t);
@@ -1948,7 +1797,7 @@
// Next is Initiator's id (ZIDi), in this case as Initiator
// it is zid
- data[pos] = ownZid;
+ data[pos] = zid;
length[pos++] = ZID_SIZE;
// Next is Responder's id (ZIDr), in this case our peer's id
@@ -1969,7 +1818,7 @@
* this length stuff again.
*/
int secretHashLen = RS_LENGTH;
- secretHashLen = zrtpHtonl(secretHashLen); // prepare 32 bit big-endian number
+ secretHashLen = htonl(secretHashLen); // prepare 32 bit big-endian number
for (int32_t i = 0; i < 3; i++) {
if (setD[i] != NULL) { // a matching secret, set length, then secret
@@ -1977,7 +1826,7 @@
data[pos] = (unsigned char*)&sLen[i];
length[pos++] = sizeof(uint32_t);
data[pos] = (unsigned char*)setD[i];
- length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+ length[pos++] = RS_LENGTH;
}
else { // no machting secret, set length 0, skip secret
sLen[i] = 0;
@@ -2002,68 +1851,47 @@
* retained secret ids. Compare them with the expected secret ids (refer
* to chapter 5.3.1 in the specification).
*/
-void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
+void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
const uint8_t* setD[3];
int32_t rsFound = 0;
setD[0] = setD[1] = setD[2] = NULL;
- detailInfo.secretsMatchedDH = 0;
- if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
- detailInfo.secretsMatchedDH |= Rs1;
- if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
- detailInfo.secretsMatchedDH |= Rs2;
-
/*
* Select the real secrets into setD
*/
- // Check which RS we shall use for first place (s1)
- detailInfo.secretsMatched = 0;
+ int matchingSecrets = 0;
if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs1();
+ setD[matchingSecrets++] = zidRec.getRs1();
rsFound = 0x1;
- detailInfo.secretsMatched = Rs1;
}
else if (memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs1();
+ setD[matchingSecrets++] = zidRec.getRs1();
rsFound = 0x2;
- detailInfo.secretsMatched = Rs1;
- }
- else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs2();
- rsFound |= 0x4;
- detailInfo.secretsMatched = Rs2;
}
else if (memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
- setD[0] = zidRec->getRs2();
+ setD[matchingSecrets++] = zidRec.getRs2();
+ rsFound |= 0x4;
+ }
+ else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
+ setD[matchingSecrets++] = zidRec.getRs2();
rsFound |= 0x8;
- detailInfo.secretsMatched = Rs2;
}
-
- if (memcmp(auxSecretIDi, dhPart->getAuxSecretId(), 8) == 0) {
- DEBUGOUT((fprintf(stdout, "Responder: Match for aux secret found\n")));
- setD[1] = auxSecret;
- detailInfo.secretsMatched |= Aux;
- detailInfo.secretsMatchedDH |= Aux;
+ /* ***** not yet supported
+ if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
+ DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
+ setD[matchingSecrets++] = ;
}
- // If we have an auxSecret but no match from peer - report this.
- if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {
- sendInfo(Warning, WarningNoExpectedAuxMatch);
- }
-
+ */
if (memcmp(pbxSecretIDi, dhPart->getPbxSecretId(), 8) == 0) {
- DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", ownZid[0])));
- setD[2] = zidRec->getMiTMData();
- detailInfo.secretsMatched |= Pbx;
- detailInfo.secretsMatchedDH |= Pbx;
- peerIsEnrolled = true;
+ DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", zid[0])));
+ setD[matchingSecrets++] = zidRec.getMiTMData();
}
// Check if some retained secrets found
if (rsFound == 0) { // no RS matches found
if (rs1Valid || rs2Valid) { // but valid RS records in cache
sendInfo(Warning, WarningNoExpectedRSMatch);
- zidRec->resetSasVerified();
- saveZidRecord = false; // Don't save RS until user verfied/confirmed SAS
+ zidRec.resetSasVerified();
}
else { // No valid RS record in cache
sendInfo(Warning, WarningNoRSMatch);
@@ -2099,7 +1927,7 @@
//Very first element is a fixed counter, big endian
counter = 1;
- counter = zrtpHtonl(counter);
+ counter = htonl(counter);
data[pos] = (unsigned char*)&counter;
length[pos++] = sizeof(uint32_t);
@@ -2117,7 +1945,7 @@
length[pos++] = ZID_SIZE;
// Next is Responder's id (ZIDr), in this case our own zid
- data[pos] = ownZid;
+ data[pos] = zid;
length[pos++] = ZID_SIZE;
// Next ist total hash (messageHash) itself
@@ -2134,7 +1962,7 @@
* this length stuff again.
*/
int secretHashLen = RS_LENGTH;
- secretHashLen = zrtpHtonl(secretHashLen); // prepare 32 bit big-endian number
+ secretHashLen = htonl(secretHashLen); // prepare 32 bit big-endian number
for (int32_t i = 0; i < 3; i++) {
if (setD[i] != NULL) { // a matching secret, set length, then secret
@@ -2142,7 +1970,7 @@
data[pos] = (unsigned char*)&sLen[i];
length[pos++] = sizeof(uint32_t);
data[pos] = (unsigned char*)setD[i];
- length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+ length[pos++] = RS_LENGTH;
}
else { // no machting secret, set length 0, skip secret
sLen[i] = 0;
@@ -2174,7 +2002,7 @@
// Very first element is a fixed counter, big endian
uint32_t counter = 1;
- counter = zrtpHtonl(counter);
+ counter = htonl(counter);
data[pos] = (unsigned char*)&counter;
length[pos++] = sizeof(uint32_t);
@@ -2187,7 +2015,7 @@
length[pos++] = contextLength;
// last element is HMAC length in bits, big endian
- uint32_t len = zrtpHtonl(L);
+ uint32_t len = htonl(L);
data[pos] = (unsigned char*)&len;
length[pos++] = sizeof(uint32_t);
@@ -2201,18 +2029,18 @@
void ZRtp::generateKeysMultiStream() {
// allocate the maximum size, compute real size to use
- uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
- int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
+ uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
+ int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
if (myRole == Responder) {
memcpy(KDFcontext, peerZid, sizeof(peerZid));
- memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+ memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
}
else {
- memcpy(KDFcontext, ownZid, sizeof(ownZid));
- memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+ memcpy(KDFcontext, zid, sizeof(zid));
+ memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
}
- memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
+ memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
KDF(zrtpSession, hashLength, (unsigned char*)zrtpMsk, strlen(zrtpMsk)+1, KDFcontext, kdfSize, hashLength*8, s0);
@@ -2224,16 +2052,16 @@
void ZRtp::computePBXSecret() {
// Construct the KDF context as per ZRTP specification chap 7.3.1:
// ZIDi || ZIDr
- uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)];
- int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid);
+ uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)];
+ int32_t kdfSize = sizeof(peerZid)+sizeof(zid);
if (myRole == Responder) {
memcpy(KDFcontext, peerZid, sizeof(peerZid));
- memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+ memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
}
else {
- memcpy(KDFcontext, ownZid, sizeof(ownZid));
- memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+ memcpy(KDFcontext, zid, sizeof(zid));
+ memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
}
KDF(zrtpSession, hashLength, (unsigned char*)zrtpTrustedMitm, strlen(zrtpTrustedMitm)+1, KDFcontext,
@@ -2246,20 +2074,20 @@
void ZRtp::computeSRTPKeys() {
// allocate the maximum size, compute real size to use
- uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
- int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
+ uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
+ int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
int32_t keyLen = cipher->getKeylen() * 8;
if (myRole == Responder) {
memcpy(KDFcontext, peerZid, sizeof(peerZid));
- memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+ memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
}
else {
- memcpy(KDFcontext, ownZid, sizeof(ownZid));
- memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+ memcpy(KDFcontext, zid, sizeof(zid));
+ memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
}
- memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
+ memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
// Inititiator key and salt
KDF(s0, hashLength, (unsigned char*)iniMasterKey, strlen(iniMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyI);
@@ -2271,13 +2099,13 @@
// The HMAC keys for GoClear
KDF(s0, hashLength, (unsigned char*)iniHmacKey, strlen(iniHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyI);
+
KDF(s0, hashLength, (unsigned char*)respHmacKey, strlen(respHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyR);
// The keys for Confirm messages
KDF(s0, hashLength, (unsigned char*)iniZrtpKey, strlen(iniZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyI);
KDF(s0, hashLength, (unsigned char*)respZrtpKey, strlen(respZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyR);
- detailInfo.pubKey = detailInfo.sasType = NULL;
if (!multiStream) {
// Compute the new Retained Secret
KDF(s0, hashLength, (unsigned char*)retainedSec, strlen(retainedSec)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, newRs1);
@@ -2285,7 +2113,7 @@
// Compute the ZRTP Session Key
KDF(s0, hashLength, (unsigned char*)zrtpSessionKey, strlen(zrtpSessionKey)+1, KDFcontext, kdfSize, hashLength*8, zrtpSession);
- // perform generation according to chapter 5.5 and 8.
+ // perform SAS generation according to chapter 5.5 and 8.
// we don't need a speciai sasValue filed. sasValue are the first
// (leftmost) 32 bits (4 bytes) of sasHash
uint8_t sasBytes[4];
@@ -2298,24 +2126,10 @@
sasBytes[1] = sasHash[1];
sasBytes[2] = sasHash[2] & 0xf0;
sasBytes[3] = 0;
- if (*(int32_t*)b32 == *(int32_t*)(sasType->getName())) {
- SAS = Base32(sasBytes, 20).getEncoded();
- }
- else {
- SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
- }
-
+ SAS = Base32(sasBytes, 20).getEncoded();
if (signSasSeen)
callback->signSAS(sasHash);
-
- detailInfo.pubKey = pubKey->getReadable();
- detailInfo.sasType = sasType->getReadable();
}
- // set algorithm names into detailInfo structure
- detailInfo.authLength = authLength->getReadable();
- detailInfo.cipher = cipher->getReadable();
- detailInfo.hash = hash->getReadable();
-
memset(KDFcontext, 0, sizeof(KDFcontext));
}
@@ -2341,25 +2155,7 @@
sec.sas = SAS;
sec.role = myRole;
- bool rc = callback->srtpSecretsReady(&sec, part);
-
- // The call state engine calls ForSender always after ForReceiver.
- if (part == ForSender) {
- std::string cs(cipher->getReadable());
- if (!multiStream) {
- cs.append("/").append(pubKey->getName());
- if (mitmSeen)
- cs.append("/EndAtMitM");
- callback->srtpSecretsOn(cs, SAS, zidRec->isSasVerified());
- }
- else {
- std::string cs1("");
- if (mitmSeen)
- cs.append("/EndAtMitM");
- callback->srtpSecretsOn(cs, cs1, true);
- }
- }
- return rc;
+ return callback->srtpSecretsReady(&sec, part);
}
@@ -2392,34 +2188,6 @@
hashCtxFunction = sha384Ctx;
hashCtxListFunction = sha384Ctx;
break;
-
- case 2:
- hashLength = SKEIN256_DIGEST_LENGTH;
- hashFunction = skein256;
- hashListFunction = skein256;
-
- hmacFunction = macSkein256;
- hmacListFunction = macSkein256;
-
- createHashCtx = createSkein256Context;
- closeHashCtx = closeSkein256Context;
- hashCtxFunction = skein256Ctx;
- hashCtxListFunction = skein256Ctx;
- break;
-
- case 3:
- hashLength = SKEIN384_DIGEST_LENGTH;
- hashFunction = skein384;
- hashListFunction = skein384;
-
- hmacFunction = macSkein384;
- hmacListFunction = macSkein384;
-
- createHashCtx = createSkein384Context;
- closeHashCtx = closeSkein384Context;
- hashCtxFunction = skein384Ctx;
- hashCtxListFunction = skein384Ctx;
- break;
}
}
@@ -2432,25 +2200,25 @@
if (paranoidMode)
return;
- zidRec->setSasVerified();
- saveZidRecord = true;
- getZidCacheInstance()->saveRecord(zidRec);
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zid = ZIDFile::getInstance();
+
+ zid->getRecord(&zidRec);
+ zidRec.setSasVerified();
+ zid->saveRecord(&zidRec);
}
void ZRtp::resetSASVerified() {
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+ ZIDFile *zid = ZIDFile::getInstance();
- zidRec->resetSasVerified();
- getZidCacheInstance()->saveRecord(zidRec);
+ zid->getRecord(&zidRec);
+ zidRec.resetSasVerified();
+ zid->saveRecord(&zidRec);
}
-void ZRtp::setRs2Valid() {
-
- if (zidRec != NULL) {
- zidRec->setRs2Valid();
- if (saveZidRecord)
- getZidCacheInstance()->saveRecord(zidRec);
- }
-}
void ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
@@ -2502,32 +2270,33 @@
}
}
-void ZRtp::setClientId(std::string id, HelloPacketVersion* hpv) {
+void ZRtp::setClientId(std::string id) {
+ if (id.size() < CLIENT_ID_SIZE) {
+ unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
+ memcpy(tmp, id.c_str(), id.size());
+ tmp[CLIENT_ID_SIZE] = 0;
+ zrtpHello.setClientId(tmp);
+ } else {
+ zrtpHello.setClientId((unsigned char*)id.c_str());
+ }
- unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
- memcpy(tmp, id.c_str(), id.size() > CLIENT_ID_SIZE ? CLIENT_ID_SIZE : id.size());
- tmp[CLIENT_ID_SIZE] = 0;
+ int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
- hpv->packet->setClientId(tmp);
-
- int32_t len = hpv->packet->getLength() * ZRTP_WORD_SIZE;
-
- // Hello packets are ready now, compute its HMAC
+ // Hello packet is ready now, compute its HMAC
// (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello
// use the implicit hash function
uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
uint32_t macLen;
- hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)hpv->packet->getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
- hpv->packet->setHMAC(hmac);
+ hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
+ zrtpHello.setHMAC(hmac);
// calculate hash over the final Hello packet, refer to chap 9.1 how to
// use this hash in SIP/SDP.
- hashFunctionImpl((uint8_t*)hpv->packet->getHeaderBase(), len, hpv->helloHash);
+ hashFunctionImpl((uint8_t*)zrtpHello.getHeaderBase(), len, helloHash);
}
void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
- uint32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
- length = (length > sizeof(tempMsgBuffer)) ? sizeof(tempMsgBuffer) : length;
+ int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
lengthOfMsgData = length;
@@ -2543,18 +2312,12 @@
return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
}
-std::string ZRtp::getHelloHash(int32_t index) {
+std::string ZRtp::getHelloHash() {
std::ostringstream stm;
- if (index < 0 || index >= MAX_ZRTP_VERSIONS)
- return std::string();
+ uint8_t* hp = helloHash;
- uint8_t* hp = helloPackets[index].helloHash;
-
- char version[5] = {'\0'};
- strncpy(version, (const char*)helloPackets[index].packet->getVersion(), ZRTP_WORD_SIZE);
-
- stm << version;
+ stm << zrtpVersion;
stm << " ";
stm.fill('0');
stm << hex;
@@ -2634,19 +2397,24 @@
void ZRtp::acceptEnrollment(bool accepted) {
if (!accepted) {
- zidRec->resetMITMKeyAvailable();
callback->zrtpInformEnrollment(EnrollmentCanceled);
- getZidCacheInstance()->saveRecord(zidRec);
return;
}
+ // Get peer's zid record to store the pbx (MitM) secret
+ // Initialize a ZID record to get peer's retained secrets
+ ZIDRecord zidRec(peerZid);
+ ZIDFile* zid = ZIDFile::getInstance();
+ zid->getRecord(&zidRec);
+
if (pbxSecretTmp != NULL) {
- zidRec->setMiTMData(pbxSecretTmp);
- getZidCacheInstance()->saveRecord(zidRec);
+ zidRec.setMiTMData(pbxSecretTmp);
callback->zrtpInformEnrollment(EnrollmentOk);
}
else {
callback->zrtpInformEnrollment(EnrollmentFailed);
+ return;
}
+ zid->saveRecord(&zidRec);
return;
}
@@ -2671,8 +2439,7 @@
Event_t ev;
ev.type = ZrtpPacket;
- ev.packet = (uint8_t*)zrtpConf2Ack.getHeaderBase();
- ev.length = sizeof (Conf2AckPacket_t) + 12; // 12 is fixed ZRTP (RTP) header size
+ ev.packet = (uint8_t*)&zrtpConf2Ack;
if (stateEngine != NULL) {
stateEngine->processEvent(&ev);
@@ -2680,8 +2447,7 @@
}
int32_t ZRtp::compareCommit(ZrtpPacketCommit *commit) {
- // TODO: enhance to compare according to rules defined in chapter 4.2,
- // but we don't support Preshared.
+ // TODO: enhance to compare according to rules defined in chapter 4.2
int32_t len = 0;
len = !multiStream ? HVI_SIZE : (4 * ZRTP_WORD_SIZE);
return (memcmp(hvi, commit->getHvi(), len));
@@ -2720,8 +2486,9 @@
randomZRTP(randomIV, sizeof(randomIV));
zrtpSasRelay.setIv(randomIV);
zrtpSasRelay.setTrustedSas(sh);
- zrtpSasRelay.setSasAlgo((uint8_t*)render.c_str());
+ zrtpSasRelay.setSas((uint8_t*)render.c_str());
+ // Encrypt and HMAC with Initiator's key - we are Initiator here
int16_t hmlen = (zrtpSasRelay.getLength() - 9) * ZRTP_WORD_SIZE;
cipher->getEncrypt()(ekey, cipher->getKeylen(), randomIV, (uint8_t*)zrtpSasRelay.getFiller(), hmlen);
@@ -2748,22 +2515,6 @@
return IDENTIFIER_LEN;
}
-const ZRtp::zrtpInfo* ZRtp::getDetailInfo() {
- return &detailInfo;
-}
-
-std::string ZRtp::getPeerClientId() {
- if (peerClientId.empty())
- return std::string();
- return peerClientId;
-}
-
-std::string ZRtp::getPeerProtcolVersion() {
- if (peerHelloVersion[0] == 0)
- return std::string();
- return std::string((char*)peerHelloVersion);
-}
-
/** EMACS **
* Local variables:
* mode: c++
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp b/jni/libzrtp/sources/src/ZrtpCWrapper.cpp
similarity index 94%
rename from jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
rename to jni/libzrtp/sources/src/ZrtpCWrapper.cpp
index 7f7c3dd..1e1d2c8 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCWrapper.cpp
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C calls to ZRTP C++ methods.
- Copyright (C) 2010-2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -19,7 +19,7 @@
#include <libzrtpcpp/ZrtpCallback.h>
#include <libzrtpcpp/ZrtpConfigure.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDFile.h>
#include <libzrtpcpp/ZRtp.h>
#include <libzrtpcpp/ZrtpCallbackWrapper.h>
#include <libzrtpcpp/ZrtpCWrapper.h>
@@ -55,7 +55,8 @@
// Initialize ZID file (cache) and get my own ZID
zrtp_initZidFile(zidFilename);
- const unsigned char* myZid = getZidCacheInstance()->getZid();
+ ZIDFile* zf = ZIDFile::getInstance();
+ const unsigned char* myZid = zf->getZid();
zrtpContext->zrtpEngine = new ZRtp((uint8_t*)myZid, zrtpContext->zrtpCallback,
clientIdString, zrtpContext->configure, mitmMode == 0 ? false : true);
@@ -79,7 +80,7 @@
}
static int32_t zrtp_initZidFile(const char* zidFilename) {
- ZIDCache* zf = getZidCacheInstance();
+ ZIDFile* zf = ZIDFile::getInstance();
if (!zf->isOpen()) {
std::string fname;
@@ -124,9 +125,9 @@
zrtpContext->zrtpEngine->stopZrtp();
}
-void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length) {
+void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC) {
if (zrtpContext && zrtpContext->zrtpEngine)
- zrtpContext->zrtpEngine->processZrtpMessage(extHeader, peerSSRC, length);
+ zrtpContext->zrtpEngine->processZrtpMessage(extHeader, peerSSRC);
}
void zrtp_processTimeout(ZrtpContext* zrtpContext) {
@@ -164,10 +165,10 @@
zrtpContext->zrtpEngine->resetSASVerified();
}
-char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index) {
+char* zrtp_getHelloHash(ZrtpContext* zrtpContext) {
std::string ret;
if (zrtpContext && zrtpContext->zrtpEngine)
- ret = zrtpContext->zrtpEngine->getHelloHash(index);
+ ret = zrtpContext->zrtpEngine->getHelloHash();
else
return NULL;
@@ -324,13 +325,6 @@
return 0;
}
-int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext) {
- return zrtpContext->zrtpEngine->getNumberSupportedVersions();
-}
-
-int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext) {
- return zrtpContext->zrtpEngine->getCurrentProtocolVersion();
-}
/*
* The following methods wrap the ZRTP Configure functions
*/
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp b/jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
similarity index 96%
rename from jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
rename to jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
index fed2c04..ca2dce6 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C++ callback methods to C callback methods.
- Copyright (C) 2010-2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp b/jni/libzrtp/sources/src/ZrtpConfigure.cpp
similarity index 85%
rename from jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
rename to jni/libzrtp/sources/src/ZrtpConfigure.cpp
index 6a22983..560466f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
+++ b/jni/libzrtp/sources/src/ZrtpConfigure.cpp
@@ -1,26 +1,5 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <crypto/aesCFB.h>
-#include <crypto/twoCFB.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/twoCFB.h>
#include <libzrtpcpp/ZrtpConfigure.h>
#include <libzrtpcpp/ZrtpTextData.h>
@@ -154,10 +133,8 @@
* Set up the enumeration list for available hash algorithms
*/
HashEnum::HashEnum() : EnumBase(HashAlgorithm) {
- insert(s256, 0, "SHA-256", NULL, NULL, None);
- insert(s384, 0, "SHA-384", NULL, NULL, None);
- insert(skn2, 0, "Skein-256", NULL, NULL, None);
- insert(skn3, 0, "Skein-384", NULL, NULL, None);
+ insert(s256);
+ insert(s384);
}
HashEnum::~HashEnum() {}
@@ -166,10 +143,10 @@
* Set up the enumeration list for available symmetric cipher algorithms
*/
SymCipherEnum::SymCipherEnum() : EnumBase(CipherAlgorithm) {
- insert(aes3, 32, "AES-256", aesCfbEncrypt, aesCfbDecrypt, Aes);
- insert(aes1, 16, "AES-128", aesCfbEncrypt, aesCfbDecrypt, Aes);
- insert(two3, 32, "Twofish-256", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
- insert(two1, 16, "TwoFish-128", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
+ insert(aes3, 32, "AES-CM-256", aesCfbEncrypt, aesCfbDecrypt, Aes);
+ insert(aes1, 16, "AES-CM-128", aesCfbEncrypt, aesCfbDecrypt, Aes);
+ insert(two3, 32, "TWO-CM-256", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
+ insert(two1, 16, "TWO-CM-128", twoCfbEncrypt, twoCfbDecrypt, TwoFish);
}
SymCipherEnum::~SymCipherEnum() {}
@@ -178,15 +155,11 @@
* Set up the enumeration list for available public key algorithms
*/
PubKeyEnum::PubKeyEnum() : EnumBase(PubKeyAlgorithm) {
- insert(dh2k, 0, "DH-2048", NULL, NULL, None);
- insert(ec25, 0, "NIST ECDH-256", NULL, NULL, None);
- insert(dh3k, 0, "DH-3072", NULL, NULL, None);
- insert(ec38, 0, "NIST ECDH-384", NULL, NULL, None);
- insert(mult, 0, "Multi-stream", NULL, NULL, None);
-#ifdef SUPPORT_NON_NIST
- insert(e255, 0, "ECDH-255", NULL, NULL, None);
- insert(e414, 0, "ECDH-414", NULL, NULL, None);
-#endif
+ insert(dh2k);
+ insert(dh3k);
+ insert(mult);
+ insert(ec25);
+ insert(ec38);
}
PubKeyEnum::~PubKeyEnum() {}
@@ -196,7 +169,6 @@
*/
SasTypeEnum::SasTypeEnum() : EnumBase(SasType) {
insert(b32);
- insert(b256);
}
SasTypeEnum::~SasTypeEnum() {}
@@ -205,10 +177,10 @@
* Set up the enumeration list for available SRTP authentications
*/
AuthLengthEnum::AuthLengthEnum() : EnumBase(AuthLength) {
- insert(hs32, 32, "HMAC-SHA1 32 bit", NULL, NULL, Sha1);
- insert(hs80, 80, "HMAC-SHA1 80 bit", NULL, NULL, Sha1);
- insert(sk32, 32, "Skein-MAC 32 bit", NULL, NULL, Skein);
- insert(sk64, 64, "Skein-MAC 64 bit", NULL, NULL, Skein);
+ insert(hs32, 32, "", NULL, NULL, Sha1);
+ insert(hs80, 80, "", NULL, NULL, Sha1);
+ insert(sk32, 32, "", NULL, NULL, Skein);
+ insert(sk64, 64, "", NULL, NULL, Skein);
}
AuthLengthEnum::~AuthLengthEnum() {}
@@ -225,8 +197,7 @@
/*
* The public methods are mainly a facade to the private methods.
*/
-ZrtpConfigure::ZrtpConfigure(): enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false),
-selectionPolicy(Standard){}
+ZrtpConfigure::ZrtpConfigure() : enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false) {}
ZrtpConfigure::~ZrtpConfigure() {}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp b/jni/libzrtp/sources/src/ZrtpCrc32.cpp
similarity index 74%
rename from jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp
rename to jni/libzrtp/sources/src/ZrtpCrc32.cpp
index 0606561..c65b19a 100755
--- a/jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCrc32.cpp
@@ -1,7 +1,46 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ *
+ * SCTP Checksum functions
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Dinakaran Joseph
+ * Jon Grimm <jgrimm@us.ibm.com>
+ * Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
/* The following code has been taken directly from
* draft-ietf-tsvwg-sctpcsum-03.txt
*
- * The code has now been modified by Werner.Dittmann@t-online.de for use
+ * The code has now been modified by Werner.Dittmann@t-online.de for use
* inside the ZRTP implementation.
*/
@@ -145,10 +184,40 @@
byte3 = (result>>24) & 0xff;
crc32 = ((byte0 << 24) |
- (byte1 << 16) |
- (byte2 << 8) |
- byte3);
+ (byte1 << 16) |
+ (byte2 << 8) |
+ byte3);
// fprintf(stderr, "Computed crc32: %x\n", crc32);
return crc32;
}
+#ifdef UNIT_TEST
+uint8_t test_data[48] = {
+ 0x01, 0xC0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xFE, 0x60, 0xAC,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x09,
+ 0x25, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+int main( int argc, char * argv[] )
+{
+ crc32c = sctp_update_cksum(test_data, 48);
+ printf("Hello World, expected result: 0x664f75eb\n");
+ printf("Result is: 0x%x\n", crc32c);
+}
+#endif
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
index 5a96f52..85f1484 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp b/jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
index b582777..af4bb09 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp b/jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
index 67a51ee..f35dc82 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp b/jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
similarity index 83%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
index 6f13cae..f558759 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -66,17 +66,6 @@
return true;
}
-bool ZrtpPacketConfirm::isSignatureLengthOk() {
- int32_t actualLen = getLength();
- int32_t expectedLen = 19; // Confirm packet fixed part is 19 ZRTP words
- int32_t sigLen = getSignatureLength();
-
- if (sigLen > 0) { // We have a signature
- expectedLen += sigLen + 1; // +1 for the signature length field
- }
- return (expectedLen == actualLen);
-}
-
int32_t ZrtpPacketConfirm::getSignatureLength() {
int32_t sl = confirmHeader->sigLength & 0xff;
if (confirmHeader->filler[1] == 1) { // do we have a 9th bit
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp b/jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
similarity index 83%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
index 1a89e16..8c59233 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -59,12 +59,6 @@
else if (*(int32_t*)pkt == *(int32_t*)ec38) {
dhLength = 96;
}
- else if (*(int32_t*)pkt == *(int32_t*)e255) {
- dhLength = 32;
- }
- else if (*(int32_t*)pkt == *(int32_t*)e414) {
- dhLength = 104;
- }
else
return;
@@ -80,24 +74,18 @@
int16_t len = getLength();
DEBUGOUT((fprintf(stdout, "DHPart length: %d\n", len)));
- if (len == 85) { // Dh2k
+ if (len == 85) {
dhLength = 256;
}
- else if (len == 117) { // Dh3k
+ else if (len == 117) {
dhLength = 384;
}
- else if (len == 37) { // EC256
+ else if (len == 37) {
dhLength = 64;
}
- else if (len == 45) { // EC384
+ else if (len == 45) {
dhLength = 96;
}
- else if (len == 29) { // E255
- dhLength = 32;
- }
- else if (len == 47) { // E414
- dhLength = 104;
- }
else {
pv = NULL;
return;
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp b/jni/libzrtp/sources/src/ZrtpPacketError.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketError.cpp
index 94d4dc1..a9d881e 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketError.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
index d0d0f33..3a30977 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketGoClear.cpp b/jni/libzrtp/sources/src/ZrtpPacketGoClear.cpp
similarity index 100%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketGoClear.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketGoClear.cpp
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp b/jni/libzrtp/sources/src/ZrtpPacketHello.cpp
similarity index 81%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketHello.cpp
index bc885ef..1a0b701 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketHello.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -19,7 +19,6 @@
* Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
*/
-#include <ctype.h>
#include <libzrtpcpp/ZrtpPacketHello.h>
@@ -63,6 +62,8 @@
setLength(length / ZRTP_WORD_SIZE);
setMessageType((uint8_t*)HelloMsg);
+ setVersion((uint8_t*)zrtpVersion);
+
uint32_t lenField = nHash << 16;
for (int32_t i = 0; i < nHash; i++) {
AlgorithmEnum& hash = config->getAlgoAt(HashAlgorithm, i);
@@ -92,7 +93,7 @@
AlgorithmEnum& sas = config->getAlgoAt(SasType, i);
setSasType(i, (int8_t*)sas.getName());
}
- *((uint32_t*)&helloHeader->flags) = zrtpHtonl(lenField);
+ *((uint32_t*)&helloHeader->flags) = htonl(lenField);
}
ZrtpPacketHello::ZrtpPacketHello(uint8_t *data) {
@@ -101,28 +102,14 @@
zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)data)->hdr; // the standard header
helloHeader = (Hello_t *)&((HelloPacket_t *)data)->hello;
- // Force the isLengthOk() check to fail when we process the packet.
- if (getLength() < HELLO_FIXED_PART_LEN) {
- computedLength = 0;
- return;
- }
-
uint32_t t = *((uint32_t*)&helloHeader->flags);
- uint32_t temp = zrtpNtohl(t);
+ uint32_t temp = ntohl(t);
nHash = (temp & (0xf << 16)) >> 16;
- nHash &= 0x7; // restrict to max 7 algorithms
nCipher = (temp & (0xf << 12)) >> 12;
- nCipher &= 0x7;
nAuth = (temp & (0xf << 8)) >> 8;
- nAuth &= 0x7;
nPubkey = (temp & (0xf << 4)) >> 4;
- nPubkey &= 0x7;
nSas = temp & 0xf;
- nSas &= 0x7;
-
- // +2 : the MAC at the end of the packet
- computedLength = nHash + nCipher + nAuth + nPubkey + nSas + sizeof(HelloPacket_t)/ZRTP_WORD_SIZE + 2;
oHash = sizeof(Hello_t);
oCipher = oHash + (nHash * ZRTP_WORD_SIZE);
@@ -135,14 +122,3 @@
ZrtpPacketHello::~ZrtpPacketHello() {
DEBUGOUT((fprintf(stdout, "Deleting Hello packet: alloc: %x\n", allocated)));
}
-
-int32_t ZrtpPacketHello::getVersionInt() {
- uint8_t* vp = getVersion();
- int32_t version = 0;
-
- if (isdigit(*vp) && isdigit(*vp+2)) {
- version = (*vp - '0') * 10;
- version += *(vp+2) - '0';
- }
- return version;
-}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
index 2849f2d..2d752b7 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp b/jni/libzrtp/sources/src/ZrtpPacketPing.cpp
similarity index 86%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketPing.cpp
index b79e4ac..9a1f90f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketPing.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -30,7 +30,7 @@
setZrtpId();
setLength((sizeof(PingPacket_t) / ZRTP_WORD_SIZE) - 1);
setMessageType((uint8_t*)PingMsg);
- setVersion((uint8_t*)zrtpVersion_11); // TODO: fix version string after clarification
+ setVersion((uint8_t*)zrtpVersion);
}
ZrtpPacketPing::ZrtpPacketPing(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
similarity index 86%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
index 0bee991..2331640 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -30,7 +30,7 @@
setZrtpId();
setLength((sizeof(PingAckPacket_t) / ZRTP_WORD_SIZE) - 1);
setMessageType((uint8_t*)PingAckMsg);
- setVersion((uint8_t*)zrtpVersion_11); // TODO: fix version string after clarification
+ setVersion((uint8_t*)zrtpVersion);
}
ZrtpPacketPingAck::ZrtpPacketPingAck(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
index a531e2f..6ff0c7a 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-20013 Werner Dittmann
+ Copyright (C) 2006-20011 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp b/jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
similarity index 95%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
index c8b7f54..d132e28 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp b/jni/libzrtp/sources/src/ZrtpQueue.cpp
similarity index 96%
rename from jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
rename to jni/libzrtp/sources/src/ZrtpQueue.cpp
index fef847e..73cb228 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
+++ b/jni/libzrtp/sources/src/ZrtpQueue.cpp
@@ -22,8 +22,8 @@
#include <string>
#include <stdio.h>
-#include <ZrtpQueue.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZrtpQueue.h>
+#include <libzrtpcpp/ZIDFile.h>
#include <libzrtpcpp/ZRtp.h>
#include <libzrtpcpp/ZrtpStateClass.h>
#include <libzrtpcpp/ZrtpUserCallback.h>
@@ -90,7 +90,7 @@
staticTimeoutProvider = new TimeoutProvider<std::string, ZrtpQueue*>();
staticTimeoutProvider->start();
}
- ZIDCache* zf = getZidCacheInstance();
+ ZIDFile* zf = ZIDFile::getInstance();
if (!zf->isOpen()) {
std::string fname;
if (zidFilename == NULL) {
@@ -119,15 +119,12 @@
void ZrtpQueue::startZrtp() {
if (zrtpEngine != NULL) {
zrtpEngine->startZrtpEngine();
- zrtpUnprotect = 0;
started = true;
}
}
void ZrtpQueue::stopZrtp() {
if (zrtpEngine != NULL) {
- if (zrtpUnprotect < 50 && !zrtpEngine->isMultiStream())
- zrtpEngine->setRs2Valid();
delete zrtpEngine;
zrtpEngine = NULL;
started = false;
@@ -161,10 +158,6 @@
// if ZRTP processing is enabled. Because valid RTP packets are
// already handled we delete any packets here after processing.
if (enableZrtp && zrtpEngine != NULL) {
- // Fixed header length + smallest ZRTP packet (includes CRC)
- if (rtn < (int32)(12 + sizeof(HelloAckPacket_t))) // data too small, dismiss
- return 0;
-
// Get CRC value into crc (see above how to compute the offset)
uint16_t temp = rtn - CRC_SIZE;
uint32_t crc = *(uint32_t*)(buffer + temp);
@@ -199,7 +192,7 @@
// store peer's SSRC, used when creating the CryptoContext
peerSSRC = packet->getSSRC();
- zrtpEngine->processZrtpMessage(extHeader, peerSSRC, rtn);
+ zrtpEngine->processZrtpMessage(extHeader, peerSSRC);
}
delete packet;
return 0;
@@ -686,9 +679,9 @@
clientIdString = id;
}
-std::string ZrtpQueue::getHelloHash(int32_t index) {
+std::string ZrtpQueue::getHelloHash() {
if (zrtpEngine != NULL)
- return zrtpEngine->getHelloHash(index);
+ return zrtpEngine->getHelloHash();
else
return std::string();
}
@@ -818,21 +811,6 @@
return 0;
}
-int32_t ZrtpQueue::getNumberSupportedVersions() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getNumberSupportedVersions();
-
- return 0;
-}
-
-int32_t ZrtpQueue::getCurrentProtocolVersion() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getCurrentProtocolVersion();
-
- return 0;
-}
-
-
IncomingZRTPPkt::IncomingZRTPPkt(const unsigned char* const block, size_t len) :
IncomingRTPPkt(block,len) {
}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
similarity index 85%
rename from jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
rename to jni/libzrtp/sources/src/ZrtpStateClass.cpp
index 2c46a4f..f77f9f9 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
+++ b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2008 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -46,9 +46,14 @@
};
-ZrtpStateClass::ZrtpStateClass(ZRtp *p) : parent(p), commitPkt(NULL), multiStream(false), secSubstate(Normal), sentVersion(0) {
+ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
+ parent = p;
+ secSubstate = Normal;
engine = new ZrtpStates(states, numberOfStates, Initial);
+ commitPkt = NULL;
+ multiStream = false;
+
// Set up timers according to ZRTP spec
T1.start = 50;
T1.maxResend = 20;
@@ -77,35 +82,21 @@
void ZrtpStateClass::processEvent(Event_t *ev) {
+ event = ev;
char *msg, first, middle, last;
uint8_t *pkt;
parent->synchEnter();
- event = ev;
if (event->type == ZrtpPacket) {
- pkt = event->packet;
- msg = (char *)pkt + 4;
- first = tolower(*msg);
- middle = tolower(*(msg+4));
+ pkt = event->packet;
+ msg = (char *)pkt + 4;
+ first = tolower(*msg);
+ middle = tolower(*(msg+4));
last = tolower(*(msg+7));
- // Sanity check of packet size for all states except WaitErrorAck.
- if (!inState(WaitErrorAck)) {
- uint16_t totalLength = *(uint16_t*)(pkt+2);
- totalLength = zrtpNtohs(totalLength) * ZRTP_WORD_SIZE;
- totalLength += 12 + sizeof(uint32_t); // 12 bytes is fixed header, uint32_t is CRC
-
- if (totalLength != ev->length) {
- fprintf(stderr, "Total length does not match received length: %d - %ld\n", totalLength, (long int)(ev->length & 0xffff));
- sendErrorPacket(MalformedPacket);
- parent->synchLeave();
- return;
- }
- }
-
// Check if this is an Error packet.
- if (first == 'e' && middle =='r' && last == ' ') {
+ if (first == 'e' && middle =='r' && last == ' ') {
/*
* Process a received Error packet.
*
@@ -123,9 +114,7 @@
else if (first == 'p' && middle == ' ' && last == ' ') {
ZrtpPacketPing ppkt(pkt);
ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);
- if (ppktAck != NULL) { // ACK only to valid PING packet, otherwise ignore it
- parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
- }
+ parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
parent->synchLeave();
return;
}
@@ -137,6 +126,7 @@
parent->synchLeave();
return;
}
+
}
/*
* Shut down protocol state engine: cancel outstanding timer, further
@@ -154,11 +144,10 @@
DEBUGOUT((cout << "Checking for match in Initial.\n"));
if (event->type == ZrtpInitial) {
- ZrtpPacketHello* hello = parent->prepareHello();
- sentVersion = hello->getVersionInt();
+ ZrtpPacketHello* hello = parent->prepareHello();
- // remember packet for easy resend in case timer triggers
- sentPacket = static_cast<ZrtpPacketBase *>(hello);
+ // remember packet for easy resend in case timer triggers
+ sentPacket = static_cast<ZrtpPacketBase *>(hello);
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
@@ -168,7 +157,7 @@
timerFailed(SevereNoTimer); // returns to state Initial
return;
}
- nextState(Detect);
+ nextState(Detect);
}
}
@@ -236,8 +225,6 @@
* - our peer acknowledged our Hello packet, we have not seen the peer's Hello yet
* - cancel timer T1 to stop resending Hello
* - switch to state AckDetected, wait for peer's Hello (F3)
- *
- * When we receive an HelloAck this also means that out partner accepted our protocol version.
*/
if (first == 'h' && last =='k') {
cancelTimer();
@@ -247,8 +234,7 @@
}
/*
* Hello:
- * - send HelloAck packet to acknowledge the received Hello packet if versions match.
- * Otherweise negotiate ZRTP versions.
+ * - send HelloAck packet to acknowledge the received Hello packet
* - use received Hello packet to prepare own Commit packet. We need to
* do it at this point because we need the hash value computed from
* peer's Hello packet. Follwing states my use the prepared Commit.
@@ -257,58 +243,7 @@
* - Don't clear sentPacket, points to Hello
*/
if (first == 'h' && last ==' ') {
- ZrtpPacketHello hpkt(pkt);
-
cancelTimer();
-
- /*
- * Check and negotiate the ZRTP protocol version first.
- *
- * This selection mechanism relies on the fact that we sent the highest supported protocol version in
- * the initial Hello packet with as stated in RFC6189, section 4.1.1
- */
- int32_t recvVersion = hpkt.getVersionInt();
- if (recvVersion > sentVersion) { // We don't support this version, stay in state with timer active
- if (startTimer(&T1) <= 0) {
- timerFailed(SevereNoTimer); // returns to state Initial
- }
- return;
- }
-
- /*
- * The versions don't match. Start negotiating versions. This negotiation stays in the Detect state.
- * Only if the received version matches our own sent version we start to send a HelloAck.
- */
- if (recvVersion != sentVersion) {
- ZRtp::HelloPacketVersion* hpv = parent->helloPackets;
-
- int32_t index;
- for (index = 0; hpv->packet && hpv->packet != parent->currentHelloPacket; hpv++, index++) // Find current sent Hello
- ;
-
- for(; index >= 0 && hpv->version > recvVersion; hpv--, index--) // find a supported version less-equal to received version
- ;
-
- if (index < 0) {
- sendErrorPacket(UnsuppZRTPVersion);
- return;
- }
- parent->currentHelloPacket = hpv->packet;
- sentVersion = parent->currentHelloPacket->getVersionInt();
-
- // remember packet for easy resend in case timer triggers
- sentPacket = static_cast<ZrtpPacketBase *>(parent->currentHelloPacket);
-
- if (!parent->sendPacketZRTP(sentPacket)) {
- sendFailed(); // returns to state Initial
- return;
- }
- if (startTimer(&T1) <= 0) {
- timerFailed(SevereNoTimer); // returns to state Initial
- return;
- }
- return;
- }
ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();
if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
@@ -317,6 +252,7 @@
}
// Use peer's Hello packet to create my commit packet, store it
// for possible later usage in state AckSent
+ ZrtpPacketHello hpkt(pkt);
commitPkt = parent->prepareCommit(&hpkt, &errorCode);
nextState(AckSent);
@@ -343,7 +279,7 @@
nextState(Detect);
}
}
- // If application calls zrtpStart() to restart discovery
+ // If application call zrtpStart() to restart discovery
else if (event->type == ZrtpInitial) {
cancelTimer();
if (!parent->sendPacketZRTP(sentPacket)) {
@@ -368,7 +304,7 @@
*
* The protocol engine got a Hello packet from peer and answered with a
* HelloAck response. According to the protocol we must also send a
- * Hello after HelloAck (refer to figure 1 in ZRTP RFC 6189, message
+ * Hello after HelloAck (refer to figure 1 in ZRTP RFC xxxx, message
* HelloACK (F2) must be followed by Hello (F3)). We use the timeout in
* this state to send the required Hello (F3).
*
@@ -411,36 +347,36 @@
*/
if (event->type == ZrtpPacket) {
pkt = event->packet;
- msg = (char *)pkt + 4;
+ msg = (char *)pkt + 4;
- first = tolower(*msg);
- last = tolower(*(msg+7));
+ first = tolower(*msg);
+ last = tolower(*(msg+7));
- /*
+ /*
* HelloAck:
* The peer answers with HelloAck to own HelloAck/Hello. Send Commit
* and try Initiator mode. The requirement defined in chapter 4.1 to
* have a complete Hello/HelloAck is fulfilled.
- * - stop Hello timer T1
- * - send own Commit message
- * - switch state to CommitSent, start Commit timer, assume Initiator
- */
- if (first == 'h' && last =='k') {
- cancelTimer();
+ * - stop Hello timer T1
+ * - send own Commit message
+ * - switch state to CommitSent, start Commit timer, assume Initiator
+ */
+ if (first == 'h' && last =='k') {
+ cancelTimer();
// remember packet for easy resend in case timer triggers
// Timer trigger received in new state CommitSend
sentPacket = static_cast<ZrtpPacketBase *>(commitPkt);
commitPkt = NULL; // now stored in sentPacket
- nextState(CommitSent);
+ nextState(CommitSent);
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
return;
}
if (startTimer(&T2) <= 0) {
timerFailed(SevereNoTimer); // returns to state Initial
- }
- return;
+ }
+ return;
}
/*
* Hello:
@@ -472,7 +408,7 @@
* - switch to state WaitDHPart2 and wait for peer's DHPart2
* - don't start timer, we are responder
*/
- if (first == 'c' && last == ' ') {
+ if (first == 'c') {
cancelTimer();
ZrtpPacketCommit cpkt(pkt);
@@ -510,7 +446,7 @@
}
/*
* Timer:
- * - resend Hello packet, stay in state, restart timer until repeat
+ * - resend Hello packet, stay in state, restart timer until repeat
* counter triggers
* - if repeat counter triggers switch to state Detect, con't clear
* sentPacket, Detect requires it to point to own Hello message
@@ -540,7 +476,7 @@
* AckDetected state.
*
* The protocol engine received a HelloAck in state Detect, thus the peer
- * acknowledged our the Hello. According to ZRT RFC 6189 our peer must send
+ * acknowledged our the Hello. According to ZRT RFC xxxx our peer must send
* its Hello until our protocol engine sees it (refer also to comment for
* state AckSent). This protocol sequence gurantees that both peers got at
* least one Hello.
@@ -575,7 +511,7 @@
/*
* Implementation for choice 1)
* Hello:
- * - Acknowledge peer's Hello, sending HelloACK (F4)
+ * - Acknowledge peers Hello, sending HelloACK (F4)
* - switch to state WaitCommit, wait for peer's Commit
* - we are going to be in the Responder role
*/
@@ -606,13 +542,13 @@
/*
* Implementation for choice 2)
* Hello:
- * - Acknowledge peer's Hello by sending Commit (F5)
+ * - Acknowledge peers Hello by sending Commit (F5)
* instead of HelloAck (F4)
* - switch to state CommitSent
* - Initiator role, thus start timer T2 to monitor timeout for Commit
*/
- if (first == 'h' && last == ' ') {
+ if (first == 'h') {
// Parse peer's packet data into a Hello packet
ZrtpPacketHello hpkt(pkt);
ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
@@ -662,7 +598,7 @@
DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
- char *msg, first, last;
+ char *msg, first;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -671,13 +607,12 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
- last = tolower(*(msg+7));
/*
* Hello:
* - resend HelloAck
* - stay in WaitCommit
*/
- if (first == 'h' && last == ' ') {
+ if (first == 'h') {
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
}
@@ -690,7 +625,7 @@
* - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode
* - don't start timer, we are responder
*/
- if (first == 'c' && last == ' ') {
+ if (first == 'c') {
ZrtpPacketCommit cpkt(pkt);
if (!multiStream) {
@@ -758,7 +693,7 @@
DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
- char *msg, first, middle, last, secondLast;
+ char *msg, first, last;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -767,9 +702,7 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
- middle = tolower(*(msg+4));
last = tolower(*(msg+7));
- secondLast = tolower(*(msg+6));
/*
* HelloAck or Hello:
@@ -777,7 +710,7 @@
* ignore it
* - no switch in state, leave timer as it is
*/
- if (first == 'h' && middle == 'o' && (last =='k' || last == ' ')) {
+ if (first == 'h' && (last =='k' || last == ' ')) {
return;
}
@@ -802,11 +735,6 @@
}
cancelTimer(); // this cancels the Commit timer T2
- if (!zpCo.isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange)) {
- sendErrorPacket(CriticalSWError);
- return;
- }
-
// if our hvi is less than peer's hvi: switch to Responder mode and
// send DHPart1 or Confirm1 packet. Peer (as Initiator) will retrigger if
// necessary
@@ -859,7 +787,7 @@
* - switch to WaitConfirm1
* - start timer to resend DHPart2 if necessary, we are Initiator
*/
- if (first == 'd' && secondLast == '1') {
+ if (first == 'd') {
cancelTimer();
sentPacket = NULL;
ZrtpPacketDHPart dpkt(pkt);
@@ -891,11 +819,6 @@
return;
}
- /*
- * Confirm1 and multi-stream mode
- * - switch off resending commit
- * - prepare Confirm2
- */
if (multiStream && (first == 'c' && last == '1')) {
cancelTimer();
ZrtpPacketConfirm cpkt(pkt);
@@ -966,7 +889,7 @@
DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
- char *msg, first, secondLast, last;
+ char *msg, first;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -975,14 +898,12 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
- last = tolower(*(msg+7));
- secondLast = tolower(*(msg+6));
/*
* Commit:
* - resend DHPart1
* - stay in state
*/
- if (first == 'c' && last == ' ') {
+ if (first == 'c') {
if (!parent->sendPacketZRTP(sentPacket)) {
return sendFailed(); // returns to state Initial
}
@@ -994,7 +915,7 @@
* - switch to WaitConfirm2
* - No timer, we are responder
*/
- if (first == 'd' && secondLast == '2') {
+ if (first == 'd') {
ZrtpPacketDHPart dpkt(pkt);
ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);
@@ -1073,14 +994,6 @@
sendErrorPacket(errorCode);
return;
}
- // according to chap 5.8: after sending Confirm2 the Initiator must
- // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
- // state.
- if (!parent->srtpSecretsReady(ForReceiver)) {
- parent->sendInfo(Severe, CriticalSWError);
- sendErrorPacket(CriticalSWError);
- return;
- }
nextState(WaitConfAck);
sentPacket = static_cast<ZrtpPacketBase *>(confirm);
@@ -1089,7 +1002,15 @@
return;
}
if (startTimer(&T2) <= 0) {
- timerFailed(SevereNoTimer); // returns to state Initial
+ timerFailed(SevereNoTimer); // returns to state Initial TODO check for return following this line
+ }
+ // according to chap 5.8: after sending Confirm2 the Initiator must
+ // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
+ // state.
+ if (!parent->srtpSecretsReady(ForReceiver)) {
+ parent->sendInfo(Severe, CriticalSWError);
+ sendErrorPacket(CriticalSWError);
+ return;
}
}
}
@@ -1135,7 +1056,7 @@
DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
- char *msg, first, secondLast, last;
+ char *msg, first, last;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -1144,7 +1065,6 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
- secondLast = tolower(*(msg+6));
last = tolower(*(msg+7));
/*
@@ -1152,7 +1072,7 @@
* - resend Confirm1 packet
* - stay in state
*/
- if ((first == 'd' && secondLast == '2') || (multiStream && (first == 'c' && last == ' '))) {
+ if (first == 'd' || (multiStream && (first == 'c' && last == ' '))) {
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
}
@@ -1179,7 +1099,8 @@
sendFailed(); // returns to state Initial
return;
}
- if (!parent->srtpSecretsReady(ForReceiver) || !parent->srtpSecretsReady(ForSender)) {
+ if (!parent->srtpSecretsReady(ForSender) ||
+ !parent->srtpSecretsReady(ForReceiver)) {
parent->sendInfo(Severe, CriticalSWError);
sendErrorPacket(CriticalSWError);
return;
@@ -1218,7 +1139,7 @@
DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
- char *msg, first, last;
+ char *msg, first;
uint8_t *pkt;
if (event->type == ZrtpPacket) {
@@ -1226,13 +1147,12 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
- last = tolower(*(msg+7));
/*
* ConfAck:
* - Switch off resending Confirm2
* - switch to SecureState
*/
- if (first == 'c' && last == 'k') {
+ if (first == 'c') {
cancelTimer();
sentPacket = NULL;
// Receiver was already enabled after sending Confirm2 packet
@@ -1276,45 +1196,44 @@
void ZrtpStateClass::evWaitClearAck(void) {
DEBUGOUT((cout << "Checking for match in ClearAck.\n"));
-// char *msg, first, last, middle;
-// uint8_t *pkt;
-//
-// if (event->type == ZrtpPacket) {
-// pkt = event->packet;
-// msg = (char *)pkt + 4;
-//
-// first = tolower(*msg);
-// middle = tolower(*(msg+4));
-// last = tolower(*(msg+7));
-//
-// /*
-// * ClearAck:
-// * - stop resending GoClear,
-// * - switch to state AckDetected, wait for peer's Hello
-// */
-// if (first == 'c' && middle == 'r' && last =='k') {
-// cancelTimer();
-// sentPacket = NULL;
-// nextState(Initial);
-// }
-// }
-// // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
-// else if (event->type == Timer) {
-// if (!parent->sendPacketZRTP(sentPacket)) {
-// sendFailed(); // returns to state Initial
-// return;
-// }
-// if (nextTimer(&T2) <= 0) {
-// timerFailed(SevereTooMuchRetries); // returns to state Initial
-// }
-// }
-// else { // unknown Event type for this state (covers Error and ZrtpClose)
-// if (event->type != ZrtpClose) {
-// parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
-// }
-// sentPacket = NULL;
-// nextState(Initial);
-// }
+ char *msg, first, last;
+ uint8_t *pkt;
+
+ if (event->type == ZrtpPacket) {
+ pkt = event->packet;
+ msg = (char *)pkt + 4;
+
+ first = tolower(*msg);
+ last = tolower(*(msg+7));
+
+ /*
+ * ClearAck:
+ * - stop resending GoClear,
+ * - switch to state AckDetected, wait for peer's Hello
+ */
+ if (first == 'c' && last =='k') {
+ cancelTimer();
+ sentPacket = NULL;
+ nextState(Initial);
+ }
+ }
+ // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
+ else if (event->type == Timer) {
+ if (!parent->sendPacketZRTP(sentPacket)) {
+ sendFailed(); // returns to state Initial
+ return;
+ }
+ if (nextTimer(&T2) <= 0) {
+ timerFailed(SevereTooMuchRetries); // returns to state Initial
+ }
+ }
+ else { // unknown Event type for this state (covers Error and ZrtpClose)
+ if (event->type != ZrtpClose) {
+ parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+ }
+ sentPacket = NULL;
+ nextState(Initial);
+ }
}
@@ -1418,7 +1337,7 @@
}
/*
* GoClear received, handle it. TODO fix go clear handling
- *
+ */
if (first == 'g' && last == 'r') {
ZrtpPacketGoClear gpkt(pkt);
ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);
@@ -1428,18 +1347,8 @@
}
// TODO Timeout to resend clear ack until user user confirmation
}
- */
}
- else if (event->type == Timer) {
- // Ignore stray timeout in this state
- ;
- }
- // unknown Event type for this state (covers Error and ZrtpClose)
- else {
- // If in secure state ingnore error events to avoid Error packet injection
- // attack - found by Dmitry Monakhov (dmonakhov@openvz.org)
- if (event->type == ErrorPkt)
- return;
+ else { // unknown Event type for this state (covers Error and ZrtpClose)
sentPacket = NULL;
parent->srtpSecretsOff(ForSender);
parent->srtpSecretsOff(ForReceiver);
diff --git a/jni/libzrtp/sources/src/ZrtpTextData.cpp b/jni/libzrtp/sources/src/ZrtpTextData.cpp
new file mode 100644
index 0000000..5861099
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZrtpTextData.cpp
@@ -0,0 +1,97 @@
+/*
+ Copyright (C) 2006-2008 Werner Dittmann
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+#include <stdint.h>
+#include <libzrtpcpp/ZrtpConfigure.h>
+// 1
+// 1234567890123456
+char clientId[] = "GNU ZRTP 2.1.0 "; // 16 chars max.
+char zrtpVersion[] = "1.10"; // must be 4 chars
+/**
+ *
+ */
+char HelloMsg[] = "Hello ";
+char HelloAckMsg[] = "HelloACK";
+char CommitMsg[] = "Commit ";
+char DHPart1Msg[] = "DHPart1 ";
+char DHPart2Msg[] = "DHPart2 ";
+char Confirm1Msg[] = "Confirm1";
+char Confirm2Msg[] = "Confirm2";
+char Conf2AckMsg[] = "Conf2ACK";
+char ErrorMsg[] = "Error ";
+char ErrorAckMsg[] = "ErrorACK";
+char GoClearMsg[] = "GoClear ";
+char ClearAckMsg[] = "ClearACK";
+char PingMsg[] = "Ping ";
+char PingAckMsg[] = "PingACK ";
+char SasRelayMsg[] = "SASrelay";
+char RelayAckMsg[] = "RelayACK";
+
+char responder[] = "Responder";
+char initiator[] = "Initiator";
+char iniMasterKey[] = "Initiator SRTP master key";
+char iniMasterSalt[] = "Initiator SRTP master salt";
+char respMasterKey[] = "Responder SRTP master key";
+char respMasterSalt[] = "Responder SRTP master salt";
+
+char iniHmacKey[] = "Initiator HMAC key";
+char respHmacKey[] = "Responder HMAC key";
+char retainedSec[] = "retained secret";
+
+char iniZrtpKey[] = "Initiator ZRTP key";
+char respZrtpKey[] = "Responder ZRTP key";
+
+char sasString[] = "SAS";
+
+char KDFString[] = "ZRTP-HMAC-KDF";
+
+char zrtpSessionKey[] = "ZRTP Session Key";
+
+char zrtpMsk[] = "ZRTP MSK";
+char zrtpTrustedMitm[] = "Trusted MiTM key";
+
+char s256[] = "S256";
+char s384[] = "S384";
+const char* mandatoryHash = s256;
+
+char aes3[] = "AES3";
+char aes2[] = "AES2";
+char aes1[] = "AES1";
+char two3[] = "2FS3";
+char two2[] = "2FS2";
+char two1[] = "2FS1";
+const char* mandatoryCipher = aes1;
+
+char dh2k[] = "DH2k";
+char ec25[] = "EC25";
+char dh3k[] = "DH3k";
+char ec38[] = "EC38";
+char mult[] = "Mult";
+const char* mandatoryPubKey = dh3k;
+
+char b32[] = "B32 ";
+const char* mandatorySasType = b32;
+
+char hs32[] = "HS32";
+char hs80[] = "HS80";
+char sk32[] = "SK32";
+char sk64[] = "SK64";
+const char* mandatoryAuthLen_1 = hs32;
+const char* mandatoryAuthLen_2 = hs80;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/Base32.h b/jni/libzrtp/sources/src/libzrtpcpp/Base32.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/Base32.h
rename to jni/libzrtp/sources/src/libzrtpcpp/Base32.h
diff --git a/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt b/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt
new file mode 100755
index 0000000..099a233
--- /dev/null
+++ b/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+if(enable_ccrtp)
+ set(ccrtp_inst ZrtpQueue.h zrtpccrtp.h ZrtpUserCallback.h TimeoutProvider.h)
+endif()
+
+install(FILES
+ ZrtpCodes.h ZrtpConfigure.h ZrtpCallback.h ZrtpCWrapper.h
+ ${ccrtp_inst} DESTINATION include/libzrtpcpp)
+
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h b/jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
similarity index 71%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
rename to jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
index 7aa3405..9f0edf7 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
@@ -55,14 +55,14 @@
public:
TPRequest( TOSubscriber tsi, int timeoutMs, const TOCommand &command):
- subscriber(tsi)
+ subscriber(tsi)
{
struct timeval tv;
gettimeofday(&tv, NULL );
when_ms = ((uint64)tv.tv_sec) * (uint64)1000 + ((uint64)tv.tv_usec) / (uint64)1000;
- when_ms += timeoutMs;
- this->command = command;
+ when_ms += timeoutMs;
+ this->command = command;
}
/**
@@ -70,18 +70,18 @@
*/
bool happensBefore(uint64 t)
{
- if (when_ms < t) {
- return true;
- }
- if (when_ms > t) {
- return false;
- }
- return false; // if equal it does not "happens_before"
+ if (when_ms < t) {
+ return true;
+ }
+ if (when_ms > t) {
+ return false;
+ }
+ return false; // if equal it does not "happens_before"
}
bool happensBefore(const TPRequest *req){
- return happensBefore(req->when_ms);
+ return happensBefore(req->when_ms);
}
/**
@@ -95,22 +95,22 @@
uint64 now = ((uint64)tv.tv_sec) * (uint64)1000 + ((uint64)tv.tv_usec) / (uint64)1000;
- if (happensBefore(now)) {
- return 0;
- }
- else {
- return (int)(when_ms - now);
- }
+ if (happensBefore(now)) {
+ return 0;
+ }
+ else {
+ return (int)(when_ms - now);
+ }
}
TOCommand getCommand()
{
- return command;
+ return command;
}
TOSubscriber getSubscriber()
{
- return subscriber;
+ return subscriber;
}
/**
@@ -121,9 +121,9 @@
*/
bool operator==(const TPRequest<TOCommand, TOSubscriber> &req)
{
- if (req.subscriber == subscriber &&
- req.command == command &&
- req.when_ms == when_ms) {
+ if (req.subscriber == subscriber &&
+ req.command == command &&
+ req.when_ms == when_ms) {
return true;
}
return false;
@@ -132,10 +132,10 @@
private:
TOSubscriber subscriber;
uint64 when_ms; // Time since Epoch in ms when the timeout
- // will happen
+ // will happen
TOCommand command; // Command that will be delivered to the
- // receiver (subscriber) of the timeout.
+ // receiver (subscriber) of the timeout.
};
/**
@@ -145,7 +145,7 @@
* @author Werner Dittmann
*/
template<class TOCommand, class TOSubscriber>
-class TimeoutProvider : public ost::Thread, ost::Event {
+ class TimeoutProvider : public ost::Thread, ost::Event {
public:
@@ -158,15 +158,15 @@
* Destructor also terminates the Timeout thread.
*/
~TimeoutProvider() {
- terminate();
+ terminate();
}
/**
* Terminates the Timeout provider thread.
*/
void stopThread(){
- stop = true;
- signal(); // signal event to waiting thread
+ stop = true;
+ signal(); // signal event to waiting thread
}
/**
@@ -183,28 +183,28 @@
void requestTimeout(int32_t time_ms, TOSubscriber subscriber, const TOCommand &command)
{
TPRequest<TOCommand, TOSubscriber>* request =
- new TPRequest<TOCommand, TOSubscriber>(subscriber, time_ms, command);
+ new TPRequest<TOCommand, TOSubscriber>(subscriber, time_ms, command);
synchLock.enter();
- if (requests.size()==0) {
- requests.push_front(request);
- signal();
- synchLock.leave();
- return;
- }
+ if (requests.size()==0) {
+ requests.push_front(request);
+ signal();
+ synchLock.leave();
+ return;
+ }
if (request->happensBefore(requests.front())) {
- requests.push_front(request);
- signal();
+ requests.push_front(request);
+ signal();
synchLock.leave();
- return;
- }
+ return;
+ }
if (requests.back()->happensBefore(request)){
- requests.push_back(request);
- signal();
+ requests.push_back(request);
+ signal();
synchLock.leave();
- return;
- }
+ return;
+ }
typename std::list<TPRequest<TOCommand, TOSubscriber>* >::iterator i;
for(i = requests.begin(); i != requests.end(); i++ ) {
@@ -213,8 +213,8 @@
break;
}
}
- signal();
- synchLock.leave();
+ signal();
+ synchLock.leave();
}
/**
@@ -234,48 +234,48 @@
}
i++;
}
- synchLock.leave();
+ synchLock.leave();
}
protected:
void run()
{
- do {
- synchLock.enter();
- int32_t time = 3600000;
- int32_t size = 0;
- if ((size = requests.size()) > 0) {
+ do {
+ synchLock.enter();
+ int32_t time = 3600000;
+ int32_t size = 0;
+ if ((size = requests.size()) > 0) {
time = requests.front()->getMsToTimeout();
}
- if (time == 0 && size > 0) {
- if (stop){ // This must be checked so that we will
- // stop even if we have timeouts to deliver.
+ if (time == 0 && size > 0) {
+ if (stop){ // This must be checked so that we will
+ // stop even if we have timeouts to deliver.
synchLock.leave();
- return;
- }
+ return;
+ }
TPRequest<TOCommand, TOSubscriber>* req = requests.front();
- TOSubscriber subs = req->getSubscriber();
- TOCommand command = req->getCommand();
+ TOSubscriber subs = req->getSubscriber();
+ TOCommand command = req->getCommand();
requests.pop_front();
- synchLock.leave(); // call the command with free Mutex
- subs->handleTimeout(command);
- continue;
- }
- synchLock.leave();
- if (stop) { // If we were told to stop while delivering
- // a timeout we will exit here
- return;
- }
- reset(); // ready to receive triggers again
+ synchLock.leave(); // call the command with free Mutex
+ subs->handleTimeout(command);
+ continue;
+ }
+ synchLock.leave();
+ if (stop) { // If we were told to stop while delivering
+ // a timeout we will exit here
+ return;
+ }
+ reset(); // ready to receive triggers again
wait(time);
- if (stop) { // If we are told to exit while waiting we
- // will exit
- return;
- }
- } while(true);
+ if (stop) { // If we are told to exit while waiting we
+ // will exit
+ return;
+ }
+ } while(true);
}
private:
@@ -287,9 +287,17 @@
ost::Mutex synchLock; // Protects the internal data structures
bool stop; // Flag to tell the worker thread
- // to terminate. Set to true and
- // wake the worker thread to
- // terminate it.
+ // to terminate. Set to true and
+ // wake the worker thread to
+ // terminate it.
};
#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h b/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h
new file mode 100644
index 0000000..0637c27
--- /dev/null
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h
@@ -0,0 +1,157 @@
+/*
+ Copyright (C) 2006-2010 Werner Dittmann
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#include <libzrtpcpp/ZIDRecord.h>
+
+#ifndef _ZIDFILE_H_
+#define _ZIDFILE_H_
+/**
+ * @file ZIDFile.h
+ * @brief ZID file management
+ *
+ * A ZID file stores (caches) some data that helps ZRTP to achives its
+ * key continuity feature. See @c ZIDRecord for further info which data
+ * the ZID file contains.
+ *
+ * @ingroup GNU_ZRTP
+ * @{
+ */
+
+/**
+ * This class implements a ZID (ZRTP Identifiers) file.
+ *
+ * The ZID file holds information about peers.
+ *
+ * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+class __EXPORT ZIDFile {
+
+private:
+
+ FILE* zidFile;
+ unsigned char associatedZid[IDENTIFIER_LEN];
+ /**
+ * The private ZID file constructor.
+ *
+ */
+ ZIDFile(): zidFile(NULL) {};
+ ~ZIDFile();
+ void createZIDFile(char* name);
+ void checkDoMigration(char* name);
+
+public:
+
+ /**
+ * Get the an instance of ZIDFile.
+ *
+ * This method just creates an instance an store a pointer to it
+ * in a static variable. The ZIDFile is a singleton, thus only
+ * <em>one</em> ZID file can be open at one time.
+ *
+ * @return
+ * A pointer to the global ZIDFile singleton instance.
+ */
+ static ZIDFile* getInstance();
+ /**
+ * Open the named ZID file and return a ZID file class.
+ *
+ * This static function either opens an existing ZID file or
+ * creates a new ZID file with the given name. The ZIDFile is a
+ * singleton, thus only <em>one</em> ZID file can be open at one
+ * time.
+ *
+ * To open another ZID file you must close the active ZID file
+ * first.
+ *
+ * @param name
+ * The name of the ZID file to open or create
+ * @return
+ * 1 if file could be opened/created, 0 if the ZID instance
+ * already has an open file, -1 if open/creation of file failed.
+ */
+ int open(char *name);
+
+ /**
+ * Check if ZIDFile has an active (open) file.
+ *
+ * @return
+ * True if ZIDFile has an active file, false otherwise
+ */
+ bool isOpen() { return (zidFile != NULL); };
+
+ /**
+ * Close the ZID file.
+ * Closes the ZID file, and prepares to open a new ZID file.
+ */
+ void close();
+
+ /**
+ * Get a ZID record from the active ZID file.
+ *
+ * The method get the identifier data from the ZID record parameter,
+ * locates the record in the ZID file and fills in the RS1, RS2, and
+ * other data.
+ *
+ * If no matching record exists in the ZID file the method creates
+ * it and fills it with default values.
+ *
+ * @param zidRecord
+ * The ZID record that contains the identifier data. The method
+ * fills in data .
+ * @return
+ * Currently always 1 to indicate sucess
+ */
+ unsigned int getRecord(ZIDRecord* zidRecord);
+
+ /**
+ * Save a ZID record into the active ZID file.
+ *
+ * This method saves the content of a ZID record into the ZID file. Before
+ * you can save the ZID record you must have performed a getRecord()
+ * first.
+ *
+ * @param zidRecord
+ * The ZID record to save.
+ * @return
+ * 1 on success
+ */
+ unsigned int saveRecord(ZIDRecord *zidRecord);
+
+ /**
+ * Get the ZID associated with this ZID file.
+ *
+ * @return
+ * Pointer to the ZID
+ */
+ const unsigned char* getZid() { return associatedZid; };
+};
+
+/**
+ * @}
+ */
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h b/jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
similarity index 81%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
index 74cc8a0..dc4691f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -15,13 +15,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _ZIDRECORDFILE_H_
-#define _ZIDRECORDFILE_H_
+#ifndef _ZIDRECORD_H_
+#define _ZIDRECORD_H_
/**
- * @file ZIDRecordFile.h
- * @brief ZID cache record management
+ * @file ZIDRecord.h
+ * @brief ZID record management
*
* A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
* to achives its key continuity feature. Please refer to the ZRTP
@@ -33,8 +33,9 @@
#include <string.h>
#include <stdint.h>
-#include <libzrtpcpp/ZIDRecord.h>
+#define IDENTIFIER_LEN 12
+#define RS_LENGTH 32
#define TIME_LENGTH 8 // 64 bit, can hold time on 64 bit systems
/**
@@ -67,6 +68,21 @@
unsigned char mitmKey[RS_LENGTH]; ///< MiTM key if available
} zidrecord2_t;
+
+#ifndef __EXPORT
+ #if defined _WIN32 || defined __CYGWIN__
+ #define __EXPORT __declspec(dllimport)
+ #define __LOCAL
+ #endif
+ #if __GNUC__ >= 4
+ #define __EXPORT __attribute__ ((visibility("default")))
+ #define __LOCAL __attribute__ ((visibility("hidden")))
+ #else
+ #define __EXPORT
+ #define __LOCAL
+ #endif
+#endif
+
static const int Valid = 0x1;
static const int SASVerified = 0x2;
static const int RS1Valid = 0x4;
@@ -86,13 +102,20 @@
*
* @author: Werner Dittmann <Werner.Dittmann@t-online.de>
*/
-class __EXPORT ZIDRecordFile: public ZIDRecord {
- friend class ZIDCacheFile;
+class __EXPORT ZIDRecord {
+ friend class ZIDFile;
private:
zidrecord2_t record;
unsigned long position;
+ /*
+ * The default constructor is private
+ */
+ ZIDRecord() {
+ record.version = 2;
+ }
+
/**
* Functions for I/O availabe for ZID file handling
*
@@ -108,21 +131,25 @@
void setValid() { record.flags |= Valid; }
public:
- /*
- * @brief The default constructor,
- */
- ZIDRecordFile() {
- memset(&record, 0, sizeof(zidrecord2_t));
- record.version = 2;
- }
-
/**
- * Set the @c ZID in the record.
+ * Create a ZID Record with given ZID data
*
- * Set the ZID in this record before calling read or save.
+ * The method creates a new ZID record and initializes its ZID
+ * data field. All other fields are set to null.
+ *
+ * An application can use this pre-initialized record to look
+ * up the associated record in the ZID file. If the record is
+ * available, the ZID record fields are filled with the stored
+ * data.
+ *
+ * @param idData
+ * Pointer to the fixed length ZID data
+ * @see ZIDFile::getRecord
*/
- void setZid(const unsigned char *zid) {
- memcpy(record.identifier, zid, IDENTIFIER_LEN);
+ ZIDRecord(const unsigned char *idData) {
+ memset(&record, 0, sizeof(zidrecord2_t));
+ memcpy(record.identifier, idData, IDENTIFIER_LEN);
+ record.version = 2;
}
/**
@@ -211,7 +238,7 @@
* @return
* Returns true is RS1 is not expired (valid), false otherwise.
*/
- bool isRs1NotExpired();
+ const bool isRs1NotExpired();
/**
* Returns pointer to RS1 data.
@@ -226,7 +253,7 @@
* @return
* Returns true is RS2 is not expired (valid), false otherwise.
*/
- bool isRs2NotExpired();
+ const bool isRs2NotExpired();
/**
* Returns pointer to RS1 data.
@@ -269,5 +296,13 @@
const unsigned char* getMiTMData() {return record.mitmKey; }
};
-#endif // ZIDRECORDSMALL
+#endif // ZIDRECORD
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
similarity index 82%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
index a20b599..4e03f28 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -41,7 +41,7 @@
#include <libzrtpcpp/ZrtpPacketSASrelay.h>
#include <libzrtpcpp/ZrtpPacketRelayAck.h>
#include <libzrtpcpp/ZrtpCallback.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDRecord.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
@@ -51,15 +51,6 @@
#define MAX_DIGEST_LENGTH 64
#define IMPL_MAX_DIGEST_LENGTH 64
-// max. number of parallel supported ZRTP protocol versions.
-#define MAX_ZRTP_VERSIONS 2
-
-// currently only 1.10 supported
-#define SUPPORTED_ZRTP_VERSIONS 1
-
-// Integer representation of highest supported ZRTP protocol version
-#define HIGHEST_ZRTP_VERION 12
-
class __EXPORT ZrtpStateClass;
class ZrtpDH;
@@ -99,33 +90,6 @@
public:
- typedef enum _secrets {
- Rs1 = 1,
- Rs2 = 2,
- Pbx = 4,
- Aux = 8
- } secrets;
-
- typedef struct _zrtpInfo {
- int32_t secretsCached;
- int32_t secretsMatched;
- int32_t secretsMatchedDH;
- const char *hash;
- const char *cipher;
- const char *pubKey;
- const char *sasType;
- const char *authLength;
- } zrtpInfo;
-
- /**
- * Faster access to Hello packets with different versions.
- */
- typedef struct _HelloPacketVersion {
- int32_t version;
- ZrtpPacketHello* packet;
- uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];
- } HelloPacketVersion;
-
/**
* Constructor intializes all relevant data but does not start the
* engine.
@@ -154,24 +118,26 @@
void stopZrtp();
/**
- * Process ZRTP message.
+ * Process RTP extension header.
*
- * The method takes the data and forwards it to the ZRTP state engine for further
- * processing. It's the caller's duty to check the ZRTP CRC and the ZRTP magic
- * cookie before calling this function.
+ * This method expects to get a pointer to the extension header of
+ * a RTP packet. The method checks if this is really a ZRTP
+ * packet. If this check fails the method returns 0 (false) in
+ * case this is not a ZRTP packet. We return a 1 if we processed
+ * the ZRTP extension header and the caller may process RTP data
+ * after the extension header as usual. The method return -1 the
+ * call shall dismiss the packet and shall not forward it to
+ * further RTP processing.
*
* @param extHeader
- * A pointer to the first byte of the ZRTP message. Refer to RFC6189.
+ * A pointer to the first byte of the extension header. Refer to
+ * RFC3550.
* @param peerSSRC
* The peer's SSRC.
- * @param length
- * of the received data packet, this includes the RTP like header
- * and the ZRTP CRC field - used to do santity checks.
- *
* @return
* Code indicating further packet handling, see description above.
*/
- void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC, size_t length);
+ void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC);
/**
* Process a timeout event.
@@ -236,25 +202,17 @@
/**
* Get the ZRTP Hello Hash data.
*
- * Use this method to get the ZRTP Hello hash data. The method
+ * Use this method to get the ZRTP Hello Hash data. The method
* returns the data as a string containing the ZRTP protocol version and
* hex-digits.
- *
- * The index defines which Hello packet to use. Each supported ZRTP procol version
- * uses a different Hello packet and thus computes different hashes.
*
* Refer to ZRTP specification, chapter 8.
- *
- * @param index
- * Hello hash of the Hello packet identfied by index. Index must be 0 <= index < MAX_ZRTP_VERSIONS.
*
* @return
- * a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'
- * SDP attribute identifier. The hello hash is available immediately after class instantiation.
- *
- * @see getNumberSupportedVersions()
+ * a std:string containing the Hello hash value as hex-digits. The
+ * hello hash is available immediately after class instantiation.
*/
- std::string getHelloHash(int index);
+ std::string getHelloHash();
/**
* Get the peer's ZRTP Hello Hash data.
@@ -493,50 +451,6 @@
*/
int32_t getPeerZid(uint8_t* data);
- /**
- * Returns a pointer to the gather detailed information structure.
- *
- * This structure contains some detailed information about the negotiated
- * algorithms, the chached and matched shared secrets.
- */
- const zrtpInfo *getDetailInfo();
-
- /**
- * Get peer's client id.
- *
- * @return the peer's client id or an empty @c string if not set.
- */
- std::string getPeerClientId();
-
- /**
- * Get peer's protocl version string.
- *
- * @return the peer's protocol version or an empty @c string if not set.
- */
- std::string getPeerProtcolVersion();
-
- /**
- * Get number of supported ZRTP protocol versions.
- *
- * @return the number of supported ZRTP protocol versions.
- */
- int32_t getNumberSupportedVersions() {return SUPPORTED_ZRTP_VERSIONS;}
-
- /**
- * Get negotiated ZRTP protocol version.
- *
- * @return the integer representation of the negotiated ZRTP protocol version.
- */
- int32_t getCurrentProtocolVersion() {return currentHelloPacket->getVersionInt();}
-
- /**
- * Validate the RS2 data if necessary.
- *
- * The cache functions stores the RS2 data but does not set its valid flag. The
- * application may decide to set this flag.
- */
- void setRs2Valid();
-
private:
friend class ZrtpStateClass;
@@ -548,7 +462,7 @@
/**
* This is my ZID that I send to the peer.
*/
- uint8_t ownZid[IDENTIFIER_LEN];
+ uint8_t zid[IDENTIFIER_LEN];
/**
* The peer's ZID
@@ -659,6 +573,7 @@
uint8_t H1[IMPL_MAX_DIGEST_LENGTH];
uint8_t H2[IMPL_MAX_DIGEST_LENGTH];
uint8_t H3[IMPL_MAX_DIGEST_LENGTH];
+ uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];
uint8_t peerHelloHash[IMPL_MAX_DIGEST_LENGTH];
uint8_t peerHelloVersion[ZRTP_WORD_SIZE + 1]; // +1 for nul byte
@@ -816,9 +731,7 @@
/**
* Pre-initialized packets.
*/
- ZrtpPacketHello zrtpHello_11;
- ZrtpPacketHello zrtpHello_12; // Prepare for ZRTP protocol version 1.2
-
+ ZrtpPacketHello zrtpHello;
ZrtpPacketHelloAck zrtpHelloAck;
ZrtpPacketConf2Ack zrtpConf2Ack;
ZrtpPacketClearAck zrtpClearAck;
@@ -834,23 +747,6 @@
ZrtpPacketSASrelay zrtpSasRelay;
ZrtpPacketRelayAck zrtpRelayAck;
- HelloPacketVersion helloPackets[MAX_ZRTP_VERSIONS + 1];
- int32_t highestZrtpVersion;
-
- /// Pointer to Hello packet sent to partner, initialized in ZRtp, modified by ZrtpStateClass
- ZrtpPacketHello* currentHelloPacket;
-
- /**
- * ZID cache record
- */
- ZIDRecord *zidRec;
-
- /**
- * Save record
- *
- * If false don't save record until user vrified and confirmed the SAS.
- */
- bool saveZidRecord;
/**
* Random IV data to encrypt the confirm data, 128 bit for AES
*/
@@ -870,11 +766,7 @@
*/
bool signSasSeen;
- uint32_t peerSSRC; // peer's SSRC, required to setup PingAck packet
-
- zrtpInfo detailInfo; // filled with some more detailded information if application would like to know
-
- std::string peerClientId; // store the peer's client Id
+ uint32_t peerSSRC; // peer's SSRC, required to setup PingAck packet
/**
* Enable or disable paranoid mode.
@@ -917,8 +809,9 @@
* The Hello packet.
* @return
* The Enum that identifies the best offered Hash algortihm. Return
- * mandatory algorithm if no match was found.
- */
+ * <code>NumSupportedHashes</code> to signal that no matching Hash algorithm
+ * was found at all.
+ */
AlgorithmEnum* findBestHash(ZrtpPacketHello *hello);
/**
@@ -932,8 +825,9 @@
* @param pk
* The id of the selected public key algorithm
* @return
- * The Enum that identifies the best offered Cipher algorithm. Return
- * mandatory algorithm if no match was found.
+ * The Enum that identifies the best offered Cipher algortihm. Return
+ * <code>NumSupportedSymCiphers</code> to signal that no matching Cipher algorithm
+ * was found at all.
*/
AlgorithmEnum* findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk);
@@ -946,8 +840,9 @@
* @param hello
* The Hello packet.
* @return
- * The Enum that identifies the best offered Public Key algorithm. Return
- * mandatory algorithm if no match was found.
+ * The Enum that identifies the best offered Public Key algortihm. Return
+ * <code>NumSupportedPubKeys</code> to signal that no matching Public Key algorithm
+ * was found at all.
*/
AlgorithmEnum* findBestPubkey(ZrtpPacketHello *hello);
@@ -955,18 +850,14 @@
* Find the best SAS algorithm that is offered in Hello.
*
* Find the best, that is the strongest, SAS algorithm that our peer
- * offers in its Hello packet. The method works as definied in RFC 6189,
- * chapter 4.1.2.
- *
- * The list of own supported public key algorithms must follow the rules
- * defined in RFC 6189, chapter 4.1.2, thus the order in the list must go
- * from fastest to slowest.
+ * offers in its Hello packet.
*
* @param hello
* The Hello packet.
* @return
- * The Enum that identifies the best offered SAS algorithm. Return
- * mandatory algorithm if no match was found.
+ * The Enum that identifies the best offered SAS algortihm. Return
+ * <code>NumSupportedSASTypes</code> to signal that no matching SAS algorithm
+ * was found at all.
*/
AlgorithmEnum* findBestSASType(ZrtpPacketHello* hello);
@@ -980,7 +871,8 @@
* The Hello packet.
* @return
* The Enum that identifies the best offered authentication length. Return
- * mandatory algorithm if no match was found.
+ * <code>NumSupportedAuthLenghts</code> to signal that no matching length
+ * was found at all.
*/
AlgorithmEnum* findBestAuthLen(ZrtpPacketHello* hello);
@@ -998,77 +890,6 @@
bool checkMultiStream(ZrtpPacketHello* hello);
/**
- * Checks if Hello packet contains a strong (384bit) hash based on selection policy.
- *
- * The function currently implements the nonNist policy only:
- * If the public key algorithm is a non-NIST ECC algorithm this function prefers
- * non-NIST HASH algorithms (Skein etc).
- *
- * If Hello packet does not contain a strong hash then this functions returns @c NULL.
- *
- * @param hello The Hello packet.
- * @param algoName name of selected PK algorithm
- * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.
- */
- AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName);
-
- /**
- * Checks if Hello packet offers a strong (256bit) symmetric cipher based on selection policy.
- *
- * The function currently implements the nonNist policy only:
- * If the public key algorithm is a non-NIST ECC algorithm this function prefers
- * non-NIST symmetric cipher algorithms (Twofish etc).
- *
- * If Hello packet does not contain a symmetric cipher then this functions returns @c NULL.
-
- * @param hello The Hello packet.
- * @param algoName name of selected PK algorithm
- * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.
- *
- * @return @c cipher algorithm if found in Hello packet, @c NULL otherwise.
- */
- AlgorithmEnum* getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
- /**
- * Checks if Hello packet contains a hash based on selection policy.
- *
- * The function currently implements the nonNist policy only:
- * If the public key algorithm is a non-NIST ECC algorithm this function prefers
- * non-NIST HASH algorithms (Skein etc).
- *
- * @param hello The Hello packet.
- * @param algoName name of selected PK algorithm
- * @return @c hash algorithm found in Hello packet.
- */
- AlgorithmEnum* getHashOffered(ZrtpPacketHello *hello, int32_t algoName);
-
- /**
- * Checks if Hello packet offers a symmetric cipher based on selection policy.
- *
- * The function currently implements the nonNist policy only:
- * If the public key algorithm is a non-NIST ECC algorithm this function prefers
- * non-NIST symmetric cipher algorithms (Twofish etc).
- *
- * @param hello The Hello packet.
- * @param algoName name of selected PK algorithm
- * @return non-NIST @c cipher algorithm if found in Hello packet, @c NULL otherwise
- */
- AlgorithmEnum* getCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
- /**
- * Checks if Hello packet offers a SRTP authentication length based on selection policy.
- *
- * The function currently implements the nonNist policy only:
- * If the public key algorithm is a non-NIST ECC algorithm this function prefers
- * non-NIST algorithms (Skein etc).
- *
- * @param hello The Hello packet.
- * @param algoName algoName name of selected PK algorithm
- * @return @c authLen algorithm found in Hello packet
- */
- AlgorithmEnum* getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName);
-
- /**
* Save the computed MitM secret to the ZID record of the peer
*/
void writeEnrollmentPBX();
@@ -1078,18 +899,16 @@
*/
void computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello);
- void computeSharedSecretSet(ZIDRecord *zidRec);
-
- void computeAuxSecretIds();
+ void computeSharedSecretSet(ZIDRecord& zidRec);
void computeSRTPKeys();
void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output);
- void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);
+ void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
- void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);
+ void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
void generateKeysMultiStream();
@@ -1462,10 +1281,8 @@
*
* @param id
* The client's id
- * @param hpv
- * Pointer to hello packet version structure.
*/
- void setClientId(std::string id, HelloPacketVersion* hpv);
+ void setClientId(std::string id);
};
/**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
index 0ad5b95..0126545 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
@@ -1,9 +1,9 @@
/*
This file defines the GNU ZRTP C-to-C++ wrapper.
- Copyright (C) 2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -565,7 +565,7 @@
* @returns
* Pointer to the ZrtpContext
*/
- ZrtpContext* zrtp_CreateWrapper(void);
+ ZrtpContext* zrtp_CreateWrapper();
/**
* Initialize the ZRTP protocol engine.
@@ -690,12 +690,10 @@
* A pointer to the first byte of the ZRTP message part.
* @param peerSSRC
* The peer's SSRC.
- * @param length of the received data packet - used to do santity checks.
- *
* @return
* Code indicating further packet handling, see description above.
*/
- void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length);
+ void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC);
/**
* Process a timeout event.
@@ -782,28 +780,21 @@
*
* Use this method to get the ZRTP Hello Hash data. The method
* returns the data as a string containing the ZRTP protocol version and
- * hex-digits.
-
- * The index defines which Hello packet to use. Each supported ZRTP procol version
- * uses a different Hello packet and thus computes different hashes.
+ * hex-digits. Refer to ZRTP specification, chapter 8.
*
- * Refer to ZRTP specification, chapter 8.
- *
- * @param index
- * Hello hash of the Hello packet identfied by index. Index must be 0 <= index < zrtp_getNumberSupportedVersions().
+ * <b>NOTE: An application may call this method if it needs this information.
+ * Usually it is not necessary.</b>
*
* @param zrtpContext
* Pointer to the opaque ZrtpContext structure.
- *
* @return
- * a pointer to a C-string that contains the Hello hash formatted according to RFC6189 section 8
- * without the leading 'a=zrtp-hash:' SDP attribute identifier. The hello hash is available
- * immediately after @c zrtp_CreateWrapper. The caller must @c free() if it does not use the
+ * a pointer to a C-string that contains the Hello hash value as
+ * hex-digits. The hello hash is available immediately after
+ * @c zrtp_CreateWrapper .
+ * The caller must @c free() if it does not use the
* hello hash C-string anymore.
- *
- * @see zrtp_getNumberSupportedVersions()
*/
- char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index);
+ char* zrtp_getHelloHash(ZrtpContext* zrtpContext);
/**
* Get the peer's ZRTP Hello Hash data.
@@ -1077,27 +1068,7 @@
int32_t zrtp_getPeerZid(ZrtpContext* zrtpContext, uint8_t* data);
- /**
- * Get number of supported ZRTP protocol versions.
- *
- * @param zrtpContext
- * Pointer to the opaque ZrtpContext structure.
- *
- * @return the number of supported ZRTP protocol versions.
- */
- int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext);
-
- /**
- * Get negotiated ZRTP protocol versions.
- *
- * @param zrtpContext
- * Pointer to the opaque ZrtpContext structure.
- *
- * @return the integer representation of the negotiated ZRTP protocol version.
- */
- int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext);
-
- /**
+ /**
* This enumerations list all configurable algorithm types.
*/
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
index 0ad18a9..23e9ca3 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -28,7 +28,20 @@
#include <string>
#include <stdint.h>
#include <libzrtpcpp/ZrtpCodes.h>
-#include <common/osSpecifics.h>
+
+#ifndef __EXPORT
+ #if defined _WIN32 || defined __CYGWIN__
+ #define __EXPORT __declspec(dllimport)
+ #define __LOCAL
+ #endif
+ #if __GNUC__ >= 4
+ #define __EXPORT __attribute__ ((visibility("default")))
+ #define __LOCAL __attribute__ ((visibility("hidden")))
+ #else
+ #define __EXPORT
+ #define __LOCAL
+ #endif
+#endif
/**
* This enum defines which role a ZRTP peer has.
@@ -46,7 +59,6 @@
* </ul>
*/
typedef enum {
- NoRole = 0, ///< ZRTP role not yet set
Responder = 1, ///< This client is in ZRTP Responder mode
Initiator ///< This client is in ZRTP Initiator mode
} Role;
@@ -118,10 +130,9 @@
* ZRTP calls this method to send a ZRTP packet via the RTP session.
*
* @param data
- * Points to ZRTP packet to send. The packet already contains a 4 bytes
- * storage at the end to store CRC.
+ * Points to ZRTP packet to send.
* @param length
- * The length in bytes of the data, including the CRC storage.
+ * The length in bytes of the data
* @return
* zero if sending failed, one if packet was send
*/
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
index 098ec06..dd739e0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C++ callback methods to C callback methods.
- Copyright (C) 2010-2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
index 1a7dd5f..a1bb6fc 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
@@ -1,10 +1,10 @@
/** @file ZrtpCodes.h
*/
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the Lesser GNU General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -73,7 +73,7 @@
* Sub-codes for Info
*/
enum InfoCodes {
- InfoHelloReceived = 1, //!< Hello received and prepared a Commit, ready to get peer's hello hash
+ InfoHelloReceived = 1, //!< Hello received, preparing a Commit
InfoCommitDHGenerated, //!< Commit: Generated a public DH key
InfoRespCommitReceived, //!< Responder: Commit received, preparing DHPart1
InfoDH1DHGenerated, //!< DH1Part: Generated a public DH key
@@ -90,15 +90,14 @@
* Sub-codes for Warning
*/
enum WarningCodes {
- WarningDHAESmismatch = 1, //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded
+ WarningDHAESmismatch = 1, //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096
WarningGoClearReceived, //!< Received a GoClear message
- WarningDHShort, //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded
+ WarningDHShort, //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096
WarningNoRSMatch, //!< No retained shared secrets available - must verify SAS
WarningCRCmismatch, //!< Internal ZRTP packet checksum mismatch - packet dropped
WarningSRTPauthError, //!< Dropping packet because SRTP authentication failed!
WarningSRTPreplayError, //!< Dropping packet because SRTP replay check failed!
- WarningNoExpectedRSMatch, //!< Valid retained shared secrets availabe but no matches found - must verify SAS
- WarningNoExpectedAuxMatch //!< Our AUX secret was set but the other peer's AUX secret does not match ours
+ WarningNoExpectedRSMatch //!< Valid retained shared secrets availabe but no matches found - must verify SAS
};
/**
@@ -151,8 +150,7 @@
* Information codes for the Enrollment user callbacks.
*/
enum InfoEnrollment {
- EnrollmentRequest = 0, //!< Aks user to confirm or deny an Enrollemnt request
- EnrollmentReconfirm, //!< User already enrolled, ask re-confirmation
+ EnrollmentRequest, //!< Aks user to confirm or deny an Enrollemnt request
EnrollmentCanceled, //!< User did not confirm the PBX enrollement
EnrollmentFailed, //!< Enrollment process failed, no PBX secret available
EnrollmentOk //!< Enrollment process for this PBX was ok
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
index bb78cef..33a824f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2009 - 2013 Werner Dittmann
+ Copyright (C) 2009 - 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -47,7 +47,7 @@
};
typedef void(*encrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);
-typedef void(*decrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);
+typedef void(*decrypt_t)(uint8_t*, int32_t, const uint8_t*, uint8_t*, int32_t);
/**
* The algorithm enumration class.
@@ -182,7 +182,7 @@
* @see zrtpSasTypes
* @see zrtpAuthLengths
*/
-class __EXPORT EnumBase {
+class EnumBase {
public:
/**
* Get an AlgorithmEnum by its name
@@ -257,41 +257,41 @@
/**
* The enumaration subclasses that contain the supported algorithm enumerations.
*/
-class __EXPORT HashEnum : public EnumBase {
+class HashEnum : public EnumBase {
public:
HashEnum();
~HashEnum();
};
-class __EXPORT SymCipherEnum : public EnumBase {
+class SymCipherEnum : public EnumBase {
public:
SymCipherEnum();
~SymCipherEnum();
};
-class __EXPORT PubKeyEnum : public EnumBase {
+class PubKeyEnum : public EnumBase {
public:
PubKeyEnum();
~PubKeyEnum();
};
-class __EXPORT SasTypeEnum : public EnumBase {
+class SasTypeEnum : public EnumBase {
public:
SasTypeEnum();
~SasTypeEnum();
};
-class __EXPORT AuthLengthEnum : public EnumBase {
+class AuthLengthEnum : public EnumBase {
public:
AuthLengthEnum();
~AuthLengthEnum();
};
-extern __EXPORT HashEnum zrtpHashes;
-extern __EXPORT SymCipherEnum zrtpSymCiphers;
-extern __EXPORT PubKeyEnum zrtpPubKeys;
-extern __EXPORT SasTypeEnum zrtpSasTypes;
-extern __EXPORT AuthLengthEnum zrtpAuthLengths;
+extern HashEnum zrtpHashes;
+extern SymCipherEnum zrtpSymCiphers;
+extern PubKeyEnum zrtpPubKeys;
+extern SasTypeEnum zrtpSasTypes;
+extern AuthLengthEnum zrtpAuthLengths;
/**
* ZRTP configuration data.
@@ -315,14 +315,6 @@
~ZrtpConfigure();
/**
- * Define the algorithm selection policies.
- */
- typedef enum _policies {
- Standard = 1,
- PreferNonNist = 2
- } Policy;
-
- /**
* Set the maximum number of algorithms per algorithm type that an application can
* configure.
*/
@@ -518,9 +510,6 @@
/// Helper function to print some internal data
void printConfiguredAlgos(AlgoTypes algoTyp);
- Policy getSelectionPolicy() {return selectionPolicy;}
- void setSelectionPolicy(Policy pol) {selectionPolicy = pol;}
-
private:
std::vector<AlgorithmEnum* > hashes;
std::vector<AlgorithmEnum* > symCiphers;
@@ -543,8 +532,6 @@
void printConfiguredAlgos(std::vector<AlgorithmEnum* >& a);
- Policy selectionPolicy;
-
protected:
public:
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
index 49eec83..ad57edd 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
index a5826c7..8beab7e 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -37,8 +37,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
-
-#include <common/osSpecifics.h>
+#include <netinet/in.h>
#include <libzrtpcpp/zrtpPacket.h>
#include <libzrtpcpp/ZrtpTextData.h>
@@ -96,7 +95,7 @@
* @return
* @c true if check was ok
*/
- bool isZrtpPacket() { return (zrtpNtohs(zrtpHeader->zrtpId) == zrtpId); };
+ bool isZrtpPacket() { return (ntohs(zrtpHeader->zrtpId) == zrtpId); };
/**
* Get the length in words of the ZRTP message
@@ -104,7 +103,7 @@
* @return
* The length in words
*/
- uint16_t getLength() { return zrtpNtohs(zrtpHeader->length); };
+ uint16_t getLength() { return ntohs(zrtpHeader->length); };
/**
* Return pointer to fixed length message type ASCII data
@@ -120,7 +119,7 @@
* @param len
* The length of the ZRTP message in words, host order
*/
- void setLength(uint16_t len) { zrtpHeader->length = zrtpHtons(len); };
+ void setLength(uint16_t len) { zrtpHeader->length = htons(len); };
/**
* Copy the message type ASCII data to ZRTP message type field
@@ -134,7 +133,7 @@
/**
* Initializes the ZRTP Id field
*/
- void setZrtpId() { zrtpHeader->zrtpId = zrtpHtons(zrtpId); }
+ void setZrtpId() { zrtpHeader->zrtpId = htons(zrtpId); }
};
/**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
index 91ca4c4..992f6d8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
similarity index 88%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
index 4b6e1eb..b23b23d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -31,11 +31,6 @@
#include <libzrtpcpp/ZrtpPacketBase.h>
-// PRSH here only for completeness. We don't support PRSH in the other ZRTP parts.
-#define COMMIT_DH_EX 29
-#define COMMIT_MULTI 25
-#define COMMIT_PRSH 27
-
/**
* Implement the Commit packet.
*
@@ -53,11 +48,6 @@
Commit_t* commitHeader; ///< Points to Commit message part
public:
- typedef enum _commitType {
- DhExchange = 1,
- MultiStream = 2
- } commitType;
-
/// Creates a Commit packet with default data
ZrtpPacketCommit();
@@ -100,10 +90,6 @@
/// Get pointer to MAC field during multi-stream mode, a fixed length byte array
uint8_t* getHMACMulti() { return commitHeader->hmac-4*ZRTP_WORD_SIZE; };
- /// Check if packet length makes sense.
- bool isLengthOk(commitType type) {int32_t len = getLength();
- return ((type == DhExchange) ? len == COMMIT_DH_EX : len == COMMIT_MULTI);}
-
/// Set hash algorithm type field, fixed length character field
void setHashType(uint8_t* text) { memcpy(commitHeader->hash, text, ZRTP_WORD_SIZE); };
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
index a6f85f5..a7c2567 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
index 283861d..b2dfbf4 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -73,7 +73,7 @@
const uint8_t* getHmac() { return confirmHeader->hmac; }
/// Get Expiration time data
- const uint32_t getExpTime() { return zrtpNtohl(confirmHeader->expTime); }
+ const uint32_t getExpTime() { return ntohl(confirmHeader->expTime); }
/// Get pointer to initial hash chain (H0) data, fixed byte array
uint8_t* getHashH0() { return confirmHeader->hashH0; }
@@ -84,11 +84,6 @@
/// get the signature length in words
int32_t getSignatureLength();
- /// Check if packet length makes sense. Confirm packets are 19 words at minumum
- bool isLengthOk() {return (getLength() >= 19); }
-
- bool isSignatureLengthOk();
-
/// set SAS verified flag
void setSASFlag() { confirmHeader->flags |= 0x4; }
@@ -102,7 +97,7 @@
void setIv(uint8_t* text) { memcpy(confirmHeader->iv, text, sizeof(confirmHeader->iv)); }
/// Set expiration time data
- void setExpTime(uint32_t t) { confirmHeader->expTime = zrtpHtonl(t); }
+ void setExpTime(uint32_t t) { confirmHeader->expTime = htonl(t); }
/// Set initial hash chain (H0) data, fixed length byte array
void setHashH0(uint8_t* t) { memcpy(confirmHeader->hashH0, t, sizeof(confirmHeader->hashH0)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
index 08737a5..d0ea4ba 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -79,9 +79,6 @@
/// Get pointer to HMAC, fixed length byte array
uint8_t* getHMAC() { return pv+dhLength; };
- /// Check if packet length makes sense. DHPart packets are 29 words at minumum, using E255
- bool isLengthOk() {return (getLength() >= 29);}
-
/// Setpublic key value, variable length byte array
void setPv(uint8_t* text) { memcpy(pv, text, dhLength); };
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
similarity index 83%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
index 679a803..d775801 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -52,10 +52,10 @@
virtual ~ZrtpPacketError();
/// Get the error code from Error message
- uint32_t getErrorCode() { return zrtpNtohl(errorHeader->errorCode); };
+ uint32_t getErrorCode() { return ntohl(errorHeader->errorCode); };
/// Set error code in Error message
- void setErrorCode(uint32_t code) {errorHeader->errorCode = zrtpHtonl(code); };
+ void setErrorCode(uint32_t code) {errorHeader->errorCode = htonl(code); };
private:
ErrorPacket_t data;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
index cfd435c..e64c8a6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2007-2013 Werner Dittmann
+ Copyright (C) 2007 - 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketGoClear.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketGoClear.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketGoClear.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketGoClear.h
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
index f5394af..0cc7403 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -28,8 +28,6 @@
#include <libzrtpcpp/ZrtpPacketBase.h>
-#define HELLO_FIXED_PART_LEN 22
-
/**
* Implement the Hello packet.
*
@@ -85,9 +83,6 @@
/// Get version number from Hello message, fixed ASCII character array
uint8_t* getVersion() { return helloHeader->version; };
- /// Get version number from Hello message as integer, only relvant digits converted
- int32_t getVersionInt();
-
/// Get client id from Hello message, fixed ASCII character array
uint8_t* getClientId() { return helloHeader->clientId; };
@@ -98,7 +93,7 @@
uint8_t* getZid() { return helloHeader->zid; };
/// Set version sting in Hello message, fixed ASCII character array
- void setVersion(const uint8_t *text) { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
+ void setVersion(uint8_t *text) { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
/// Set client id in Hello message, fixed ASCII character array
void setClientId(const uint8_t *t) { memcpy(helloHeader->clientId, t, sizeof(helloHeader->clientId)); }
@@ -176,20 +171,16 @@
int32_t getNumAuth() {return nAuth; }
/// set MitM flag
- void setMitmMode() {helloHeader->flags |= 0x20; }
+ void setMitmMode() { helloHeader->flags |= 0x20; }
/// set SAS sign flag
- void setSasSign() {helloHeader->flags |= 0x40; }
-
- /// Check if packet length matches
- bool isLengthOk() {return (computedLength == getLength());}
+ void setSasSign() { helloHeader->flags |= 0x40; }
private:
- uint32_t computedLength;
// Hello packet is of variable length. It maximum size is 46 words:
- // - 20 words fixed sizze
+ // - 11 words fixed sizze
// - up to 35 words variable part, depending on number of algorithms
- // leads to a maximum of 4*55=220 bytes.
+ // leads to a maximum of 4*46=184 bytes.
uint8_t data[256]; // large enough to hold a full blown Hello packet
};
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
index d3e138e..345a071 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
similarity index 92%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
index 32fb2f9..840df62 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
index eb2924f..51ad8c8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -49,13 +49,13 @@
virtual ~ZrtpPacketPingAck();
/// Get SSRC from PingAck message
- uint32_t getSSRC() { return zrtpNtohl(pingAckHeader->ssrc); };
+ uint32_t getSSRC() { return ntohl(pingAckHeader->ssrc); };
/// Set ZRTP protocol version field, fixed ASCII character array
void setVersion(uint8_t *text) { memcpy(pingAckHeader->version, text, ZRTP_WORD_SIZE ); }
/// Set SSRC in PingAck message
- void setSSRC(uint32_t data) {pingAckHeader->ssrc = zrtpHtonl(data); };
+ void setSSRC(uint32_t data) {pingAckHeader->ssrc = htonl(data); };
/// Set remote endpoint hash, fixed byte array
void setRemoteEpHash(uint8_t *hash) { memcpy(pingAckHeader->remoteEpHash, hash, sizeof(pingAckHeader->remoteEpHash)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
index 7fe373b..93437e6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2007-2013 Werner Dittmann
+ Copyright (C) 2007 - 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
similarity index 86%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
index 22739ff..427ac28 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2011 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -70,17 +70,14 @@
const uint8_t* getHmac() { return sasRelayHeader->hmac; }
/// Get pointer to new SAS rendering algorithm, fixed byte array
- const uint8_t* getSasAlgo() {return sasRelayHeader->sas; }
+ const uint8_t* getSas() {return sasRelayHeader->sas; }
/// Get pointer to new SAS hash data, fixed byte array
- const uint8_t* getTrustedSas() { return sasRelayHeader->trustedSasHash; }
+ const uint8_t* getTrustedSas() { return sasRelayHeader->trustedSasHash; }
/// get the signature length in words
uint32_t getSignatureLength();
- /// Check if packet length makes sense. SAS rely packets are 19 words at minumum, they are similar to Confirm
- bool isLengthOk() {return (getLength() >= 19);}
-
/// set SAS verified flag
void setSASFlag() { sasRelayHeader->flags |= 0x4; }
@@ -91,7 +88,7 @@
void setIv(uint8_t* text) { memcpy(sasRelayHeader->iv, text, sizeof(sasRelayHeader->iv)); }
/// Set SAS rendering algorithm, fixed length byte array
- void setSasAlgo(uint8_t* text) { memcpy(sasRelayHeader->sas, text, sizeof(sasRelayHeader->sas)); }
+ void setSas(uint8_t* text) { memcpy(sasRelayHeader->sas, text, sizeof(sasRelayHeader->sas)); }
/// Set SAS hash data, fixed length byte array
void setTrustedSas(uint8_t* text) { memcpy(sasRelayHeader->trustedSasHash, text, sizeof(sasRelayHeader->trustedSasHash)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
index 512d8c8..b979ada 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
@@ -21,8 +21,8 @@
#include <ccrtp/cqueue.h>
#include <ccrtp/rtppkt.h>
#include <libzrtpcpp/ZrtpCallback.h>
+#include <libzrtpcpp/TimeoutProvider.h>
#include <libzrtpcpp/ZrtpConfigure.h>
-#include <CcrtpTimeoutProvider.h>
class __EXPORT ZrtpUserCallback;
class __EXPORT ZRtp;
@@ -368,28 +368,20 @@
*/
void setClientId(std::string id);
- /**
+ /**
* Get the ZRTP Hello Hash data.
*
- * Use this method to get the ZRTP Hello hash data. The method
- * returns the data as a string containing the ZRTP protocol version and
- * hex-digits.
- *
- * The index defines which Hello packet to use. Each supported ZRTP procol version
- * uses a different Hello packet and thus computes different hashes.
- *
- * Refer to ZRTP specification, chapter 8.
- *
- * @param index
- * Hello hash of the Hello packet identfied by index. Index must be 0 <= index < getNumberSupportedVersions().
+ * Use this method to get the ZRTP Hello Hash data. The method
+ * returns the data as a string containing hex-digits. Refer
+ * to ZRTP specification, chapter 9.1.
*
* @return
- * a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'
- * SDP attribute identifier. The hello hash is available immediatly after class instantiation.
- *
- * @see getNumberSupportedVersions()
+ * a std:string containing the Hello hash value as hex-digits. The
+ * hello hash is available immediatly after calling
+ * ZrtpQueue#startZrtp. If ZRTP was not started the method returns
+ * an empty string.
*/
- std::string getHelloHash(int32_t index);
+ std::string getHelloHash();
/**
* Get the peer's ZRTP Hello Hash data.
@@ -751,20 +743,6 @@
*/
int32 getPeerZid(uint8* data);
- /**
- * Get number of supported ZRTP protocol versions.
- *
- * @return the number of supported ZRTP protocol versions.
- */
- int32_t getNumberSupportedVersions();
-
- /**
- * Get negotiated ZRTP protocol version.
- *
- * @return the integer representation of the negotiated ZRTP protocol version.
- */
- int32_t getCurrentProtocolVersion();
-
protected:
friend class TimeoutProvider<std::string, ost::ZrtpQueue*>;
@@ -873,7 +851,6 @@
int16 senderZrtpSeqNo;
ost::Mutex synchLock; // Mutex for ZRTP (used by ZrtpStateClass)
uint32 peerSSRC;
- uint64 zrtpUnprotect;
bool started;
bool mitmMode;
bool signSas;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
index 5c16313..fba061d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -74,7 +74,6 @@
/// A ZRTP state event
typedef struct Event {
EventDataType type; ///< Type of event
- size_t length; ///< length of the message data
uint8_t* packet; ///< Event data if availabe, usually a ZRTP message
} Event_t;
@@ -161,11 +160,6 @@
*/
bool subEvWaitRelayAck();
- /**
- * Hello packet version sent to other partner
- */
- int32_t sentVersion;
-
public:
/// Create a ZrtpStateClass
ZrtpStateClass(ZRtp *p);
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
similarity index 94%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
index e90a543..44662a0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
similarity index 86%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
index 0be1e56..e79cb98 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -37,12 +37,8 @@
*
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
-
-extern char zrtpBuildInfo[];
-
extern char clientId[];
-extern char zrtpVersion_11[];
-extern char zrtpVersion_12[];
+extern char zrtpVersion[];
/**
*
@@ -91,8 +87,6 @@
extern char s256[];
extern char s384[];
-extern char skn2[];
-extern char skn3[];
extern const char* mandatoryHash;
extern char aes3[];
@@ -108,15 +102,12 @@
extern char dh3k[];
extern char ec25[];
extern char ec38[];
-extern char e255[];
-extern char e414[];
extern char mult[];
extern const char* mandatoryPubKey;
extern char b32[];
-extern char b256[];
extern const char* mandatorySasType;
extern char hs32[];
@@ -126,9 +117,6 @@
extern const char* mandatoryAuthLen_1;
extern const char* mandatoryAuthLen_2;
-extern const char* sas256WordsOdd[];
-extern const char* sas256WordsEven[];
-
/**
* @}
*/
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
index d3c9f9d..3e4871c 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2008 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
similarity index 90%
rename from jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
index d4f7042..be3dda4 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
@@ -36,12 +36,13 @@
#include <string.h>
-#include <zrtp/crypto/twoCFB.h>
-#include <cryptcommon/twofish.h>
+#include <libzrtpcpp/crypto/twoCFB.h>
+#include <libzrtpcpp/crypto/twofish.h>
static int initialized = 0;
-void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
+void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+ int32_t dataLength)
{
Twofish_key keyCtx;
int usedBytes = 0;
@@ -59,7 +60,8 @@
}
-void twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
+void twoCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
+ int32_t dataLength)
{
Twofish_key keyCtx;
int usedBytes = 0;
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
index d2a3a40..bd32f7f 100644
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
@@ -23,9 +23,10 @@
#define _ZRTPDH_H__
#include <stdint.h>
+#include <libzrtpcpp/ZrtpConfigure.h>
/**
- * @file zrtpDH.h
+ * @file ZrtpDH.h
* @brief Class that implemets Diffie-Helman key agreement for ZRTP
*
* @ingroup GNU_ZRTP
@@ -42,25 +43,12 @@
* @param length
* Number of random bytes to produce.
*/
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
void randomZRTP(uint8_t *buf, int32_t length);
-#if defined(__cplusplus)
-}
-#endif
-
-#if defined(__cplusplus)
-
-#include <libzrtpcpp/ZrtpConfigure.h>
const int32_t DH2K = 0;
const int32_t DH3K = 1;
const int32_t EC25 = 2;
const int32_t EC38 = 3;
-const int32_t E255 = 4;
-const int32_t E414 = 5;
/**
@@ -164,8 +152,8 @@
*/
const char* getDHtype();
};
-#endif /*__cpluscplus */
-#endif
+
+#endif // ZRTPDH_H
/**
* @}
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/crypto/aesCFB.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
index 7223bdf..6b4ab6e 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -79,7 +79,7 @@
* Length of the data in bytes
*/
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
int32_t dataLength);
/**
* @}
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
similarity index 95%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
index 1c743d2..78fad51 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -17,7 +17,7 @@
#include <stdio.h>
-#include <string.h>
+#include <malloc.h>
#include <pthread.h>
#include <errno.h>
#include <gcrypt.h>
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
similarity index 88%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
index 066035f..8d06a89 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -21,7 +21,7 @@
*/
#include <gcrypt.h>
-#include <crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
extern void initializeGcrypt();
@@ -51,7 +51,7 @@
gcry_cipher_close(tmp);
}
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
int32_t dataLength);
{
gcry_error_t err = 0;
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
index bc8897a..1aba680 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006, 2013 Werner Dittmann
+ Copyright (C) 2006, 2009 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -21,8 +21,8 @@
*/
#include <gcrypt.h>
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/ZrtpTextData.h>
#include <sstream>
struct gcryptCtx {
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
index a0ecc65..3a44504 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -21,7 +21,7 @@
*/
#include <gcrypt.h>
-#include <crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
void hmac_sha256(uint8_t* key, uint32_t keyLength,
uint8_t* data, int32_t dataLength,
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
similarity index 97%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
index aa852c4..c48813c 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
@@ -21,7 +21,7 @@
*/
#include <gcrypt.h>
-#include <crypto/hmac384.h>
+#include <libzrtpcpp/crypto/hmac384.h>
void hmac_sha384(uint8_t* key, uint32_t keyLength,
uint8_t* data, int32_t dataLength,
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
similarity index 93%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
index b20bfe6..0c32bd8 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -22,7 +22,7 @@
*/
#include <gcrypt.h>
-#include <crypto/sha256.h>
+#include <libzrtpcpp/crypto/sha256.h>
void sha256(unsigned char* data, unsigned int dataLength,
unsigned char* mac)
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
similarity index 93%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
index c26a23c..19c8c5b 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -22,7 +22,7 @@
*/
#include <gcrypt.h>
-#include <crypto/sha384.h>
+#include <libzrtpcpp/crypto/sha384.h>
void sha384(unsigned char* data, unsigned int dataLength,
unsigned char* mac)
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac256.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/crypto/hmac256.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac256.h
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac384.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/crypto/hmac384.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac384.h
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
index bac29f5..595d1ff 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
@@ -38,7 +38,7 @@
#include <openssl/aes.h>
#include <string.h>
-#include <zrtp/crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
// extern void initializeOpenSSL();
@@ -66,7 +66,7 @@
}
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
int32_t dataLength)
{
AES_KEY aesKey;
@@ -85,5 +85,5 @@
return;
}
AES_cfb128_encrypt(data, data, dataLength, &aesKey,
- IV, &usedBytes, AES_DECRYPT);
+ (unsigned char*)IV, &usedBytes, AES_DECRYPT);
}
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
similarity index 97%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
index 2c5c8de..ef0c926 100755
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006 Werner Dittmann
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
similarity index 99%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
index d5b8cc9..fbd623c 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
@@ -46,8 +46,8 @@
#include <openssl/ec.h>
#include <openssl/ecdh.h>
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/ZrtpTextData.h>
// extern void initializeOpenSSL();
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
index 40e4e82..a054c02 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
@@ -36,7 +36,7 @@
*/
#include <openssl/hmac.h>
-#include <crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
void hmac_sha256(uint8_t* key, uint32_t key_length,
uint8_t* data, int32_t data_length,
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
index 8181cd6..10d6fbc 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
@@ -36,9 +36,11 @@
*/
#include <openssl/hmac.h>
-#include <zrtp/crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
-void hmac_sha384(uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length)
+void hmac_sha384(uint8_t* key, uint32_t key_length,
+ uint8_t* data, int32_t data_length,
+ uint8_t* mac, uint32_t* mac_length)
{
unsigned int tmp;
HMAC( EVP_sha384(), key, key_length, data, data_length, mac, &tmp );
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
index bc2e222..2163a6d 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
@@ -38,7 +38,7 @@
#include <openssl/crypto.h>
#include <openssl/sha.h>
-#include <crypto/sha256.h>
+#include <libzrtpcpp/crypto/sha256.h>
void sha256(unsigned char *data, unsigned int data_length,
unsigned char *digest )
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
index 9fcf316..9d166e7 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
@@ -38,7 +38,7 @@
#include <openssl/crypto.h>
#include <openssl/sha.h>
-#include <crypto/sha384.h>
+#include <libzrtpcpp/crypto/sha384.h>
void sha384(unsigned char *data, unsigned int data_length,
unsigned char *digest )
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha256.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/crypto/sha256.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
index 36127b9..959a620 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/crypto/sha384.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
index d4ccce5..6cb7a70 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/crypto/twoCFB.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
index 595d19d..593a59c 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -56,7 +56,8 @@
* Length of the data in bytes
*/
-void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);
+void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+ int32_t dataLength);
/**
* Decrypt data with Twofish CFB mode, full block feedback size.
@@ -78,7 +79,8 @@
* Length of the data in bytes
*/
-void twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);
+void twoCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
+ int32_t dataLength);
/**
* @}
*/
diff --git a/jni/libzrtp/sources/cryptcommon/twofish.c b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/twofish.c
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
index 03d2770..3d390ea 100644
--- a/jni/libzrtp/sources/cryptcommon/twofish.c
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
@@ -1,1742 +1,1733 @@
-/*
- * Fast, portable, and easy-to-use Twofish implementation,
- * Version 0.3.
- * Copyright (c) 2002 by Niels Ferguson.
- * (See further down for the almost-unrestricted licensing terms.)
- *
- * --------------------------------------------------------------------------
- * There are two files for this implementation:
- * - twofish.h, the header file.
- * - twofish.c, the code file.
- *
- * To incorporate this code into your program you should:
- * - Check the licensing terms further down in this comment.
- * - Fix the two type definitions in twofish.h to suit your platform.
- * - Fix a few definitions in twofish.c in the section marked
- * PLATFORM FIXES. There is one important ones that affects
- * functionality, and then a few definitions that you can optimise
- * for efficiency but those have no effect on the functionality.
- * Don't change anything else.
- * - Put the code in your project and compile it.
- *
- * To use this library you should:
- * - Call Twofish_initialise() in your program before any other function in
- * this library.
- * - Use Twofish_prepare_key(...) to convert a key to internal form.
- * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt
- * data.
- * See the comments in the header file for details on these functions.
- * --------------------------------------------------------------------------
- *
- * There are many Twofish implementation available for free on the web.
- * Most of them are hard to integrate into your own program.
- * As we like people to use our cipher, I thought I would make it easier.
- * Here is a free and easy-to-integrate Twofish implementation in C.
- * The latest version is always available from my personal home page at
- * http://niels.ferguson.net/
- *
- * Integrating library code into a project is difficult because the library
- * header files interfere with the project's header files and code.
- * And of course the project's header files interfere with the library code.
- * I've tried to resolve these problems here.
- * The header file of this implementation is very light-weight.
- * It contains two typedefs, a structure, and a few function declarations.
- * All names it defines start with "Twofish_".
- * The header file is therefore unlikely to cause problems in your project.
- * The code file of this implementation doesn't need to include the header
- * files of the project. There is thus no danger of the project interfering
- * with all the definitions and macros of the Twofish code.
- * In most situations, all you need to do is fill in a few platform-specific
- * definitions in the header file and code file,
- * and you should be able to run the Twofish code in your project.
- * I estimate it should take you less than an hour to integrate this code
- * into your project, most of it spent reading the comments telling you what
- * to do.
- *
- * For people using C++: it is very easy to wrap this library into a
- * TwofishKey class. One of the big advantages is that you can automate the
- * wiping of the key material in the destructor. I have not provided a C++
- * class because the interface depends too much on the abstract base class
- * you use for block ciphers in your program, which I don't know about.
- *
- * This implementation is designed for use on PC-class machines. It uses the
- * Twofish 'full' keying option which uses large tables. Total table size is
- * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key.
- * If you need an implementation that uses less memory,
- * take a look at Brian Gladman's code on his web site:
- * http://fp.gladman.plus.com/cryptography_technology/aes/
- * He has code for all AES candidates.
- * His Twofish code has lots of options trading off table size vs. speed.
- * You can also take a look at the optimised code by Doug Whiting on the
- * Twofish web site
- * http://www.counterpane.com/twofish.html
- * which has loads of options.
- * I believe these existing implementations are harder to re-use because they
- * are not clean libraries and they impose requirements on the environment.
- * This implementation is very careful to minimise those,
- * and should be easier to integrate into any larger program.
- *
- * The default mode of this implementation is fully portable as it uses no
- * behaviour not defined in the C standard. (This is harder than you think.)
- * If you have any problems porting the default mode, please let me know
- * so that I can fix the problem. (But only if this code is at fault, I
- * don't fix compilers.)
- * Most of the platform fixes are related to non-portable but faster ways
- * of implementing certain functions.
- *
- * In general I've tried to make the code as fast as possible, at the expense
- * of memory and code size. However, C does impose limits, and this
- * implementation will be slower than an optimised assembler implementation.
- * But beware of assembler implementations: a good Pentium implementation
- * uses completely different code than a good Pentium II implementation.
- * You basically have to re-write the assembly code for every generation of
- * processor. Unless you are severely pressed for speed, stick with C.
- *
- * The initialisation routine of this implementation contains a self-test.
- * If initialisation succeeds without calling the fatal routine, then
- * the implementation works. I don't think you can break the implementation
- * in such a way that it still passes the tests, unless you are malicious.
- * In other words: if the initialisation routine returns,
- * you have successfully ported the implementation.
- * (Or not implemented the fatal routine properly, but that is your problem.)
- *
- * I'm indebted to many people who helped me in one way or another to write
- * this code. During the design of Twofish and the AES process I had very
- * extensive discussions of all implementation issues with various people.
- * Doug Whiting in particular provided a wealth of information. The Twofish
- * team spent untold hours discussion various cipher features, and their
- * implementation. Brian Gladman implemented all AES candidates in C,
- * and we had some fruitful discussions on how to implement Twofish in C.
- * Jan Nieuwenhuizen tested this code on Linux using GCC.
- *
- * Now for the license:
- * The author hereby grants a perpetual license to everybody to
- * use this code for any purpose as long as the copyright message is included
- * in the source code of this or any derived work.
- *
- * Yes, this means that you, your company, your club, and anyone else
- * can use this code anywhere you want. You can change it and distribute it
- * under the GPL, include it in your commercial product without releasing
- * the source code, put it on the web, etc.
- * The only thing you cannot do is remove my copyright message,
- * or distribute any source code based on this implementation that does not
- * include my copyright message.
- *
- * I appreciate a mention in the documentation or credits,
- * but I understand if that is difficult to do.
- * I also appreciate it if you tell me where and why you used my code.
- *
- * Please send any questions or comments to niels@ferguson.net
- *
- * Have Fun!
- *
- * Niels
- */
-
-/*
- * DISCLAIMER: As I'm giving away my work for free, I'm of course not going
- * to accept any liability of any form. This code, or the Twofish cipher,
- * might very well be flawed; you have been warned.
- * This software is provided as-is, without any kind of warrenty or
- * guarantee. And that is really all you can expect when you download
- * code for free from the Internet.
- *
- * I think it is really sad that disclaimers like this seem to be necessary.
- * If people only had a little bit more common sense, and didn't come
- * whining like little children every time something happens....
- */
-
-/*
- * Version history:
- * Version 0.0, 2002-08-30
- * First written.
- * Version 0.1, 2002-09-03
- * Added disclaimer. Improved self-tests.
- * Version 0.2, 2002-09-09
- * Removed last non-portabilities. Default now works completely within
- * the C standard. UInt32 can be larger than 32 bits without problems.
- * Version 0.3, 2002-09-28
- * Bugfix: use instead of to adhere to ANSI/ISO.
- * Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library
- * header already defines BIG_ENDIAN, even though it is not
- * supposed to.
- */
-
-
-/*
- * Minimum set of include files.
- * You should not need any application-specific include files for this code.
- * In fact, adding you own header files could break one of the many macros or
- * functions in this file. Be very careful.
- * Standard include files will probably be ok.
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-/* #include * for memset(), memcpy(), and memcmp() */
-#include "twofish.h"
-
-
-/*
- * PLATFORM FIXES
- * ==============
- *
- * Fix the type definitions in twofish.h first!
- *
- * The following definitions have to be fixed for each particular platform
- * you work on. If you have a multi-platform program, you no doubt have
- * portable definitions that you can substitute here without changing the
- * rest of the code.
- */
-
-
-/*
- * Function called if something is fatally wrong with the implementation.
- * This fatal function is called when a coding error is detected in the
- * Twofish implementation, or when somebody passes an obviously erroneous
- * parameter to this implementation. There is not much you can do when
- * the code contains bugs, so we just stop.
- *
- * The argument is a string. Ideally the fatal function prints this string
- * as an error message. Whatever else this function does, it should never
- * return. A typical implementation would stop the program completely after
- * printing the error message.
- *
- * This default implementation is not very useful,
- * but does not assume anything about your environment.
- * It will at least let you know something is wrong....
- * I didn't want to include any libraries to print and error or so,
- * as this makes the code much harder to integrate in a project.
- *
- * Note that the Twofish_fatal function may not return to the caller.
- * Unfortunately this is not something the self-test can test for,
- * so you have to make sure of this yourself.
- *
- * If you want to call an external function, be careful about including
- * your own header files here. This code uses a lot of macros, and your
- * header file could easily break it. Maybe the best solution is to use
- * a separate extern statement for your fatal function.
- */
-/* #define Twofish_fatal(pmsgx) { fprintf(stderr, pmsgx); exit(1); } */
-#define Twofish_fatal(pmsgx, code) { return(code); }
-
-
-/*
- * The rest of the settings are not important for the functionality
- * of this Twofish implementation. That is, their default settings
- * work on all platforms. You can change them to improve the
- * speed of the implementation on your platform. Erroneous settings
- * will result in erroneous implementations, but the self-test should
- * catch those.
- */
-
-
-/*
- * Macros to rotate a Twofish_UInt32 value left or right by the
- * specified number of bits. This should be a 32-bit rotation,
- * and not rotation of, say, 64-bit values.
- *
- * Every encryption or decryption operation uses 32 of these rotations,
- * so it is a good idea to make these macros efficient.
- *
- * This fully portable definition has one piece of tricky stuff.
- * The UInt32 might be larger than 32 bits, so we have to mask
- * any higher bits off. The simplest way to do this is to 'and' the
- * value first with 0xffffffff and then shift it right. An optimising
- * compiler that has a 32-bit type can optimise this 'and' away.
- *
- * Unfortunately there is no portable way of writing the constant
- * 0xffffffff. You don't know which suffix to use (U, or UL?)
- * The UINT32_MASK definition uses a bit of trickery. Shift-left
- * is only defined if the shift amount is strictly less than the size
- * of the UInt32, so we can't use (1<<32). The answer it to take the value
- * 2, cast it to a UInt32, shift it left 31 positions, and subtract one.
- * Another example of how to make something very simple extremely difficult.
- * I hate C.
- *
- * The rotation macros are straightforward.
- * They are only applied to UInt32 values, which are _unsigned_
- * so the >> operator must do a logical shift that brings in zeroes.
- * On most platforms you will only need to optimise the ROL32 macro; the
- * ROR32 macro is not inefficient on an optimising compiler as all rotation
- * amounts in this code are known at compile time.
- *
- * On many platforms there is a faster solution.
- * For example, MS compilers have the __rotl and __rotr functions
- * that generate x86 rotation instructions.
- */
-#define UINT32_MASK ( (((Twofish_UInt32)2)<<31) - 1 )
-
-#ifndef _MSC_VER
-#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) )
-#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) )
-#else
-#define ROL32(x,n) (_lrotl((x), (n)))
-#define ROR32(x,n) (_lrotr((x), (n)))
-#endif
-
-/*
- * Select data type for q-table entries.
- *
- * Larger entry types cost more memory (1.5 kB), and might be faster
- * or slower depending on the CPU and compiler details.
- *
- * This choice only affects the static data size and the key setup speed.
- * Functionality, expanded key size, or encryption speed are not affected.
- * Define to 1 to get large q-table entries.
- */
-#define LARGE_Q_TABLE 0 /* default = 0 */
-
-
-/*
- * Method to select a single byte from a UInt32.
- * WARNING: non-portable code if set; might not work on all platforms.
- *
- * Inside the inner loop of Twofish it is necessary to access the 4
- * individual bytes of a UInt32. This can be done using either shifts
- * and masks, or memory accesses.
- *
- * Set to 0 to use shift and mask operations for the byte selection.
- * This is more ALU intensive. It is also fully portable.
- *
- * Set to 1 to use memory accesses. The UInt32 is stored in memory and
- * the individual bytes are read from memory one at a time.
- * This solution is more memory-intensive, and not fully portable.
- * It might be faster on your platform, or not. If you use this option,
- * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately.
- *
- * This macro does not affect the conversion of the inputs and outputs
- * of the cipher. See the CONVERT_USING_CASTS macro for that.
- */
-#define SELECT_BYTE_FROM_UINT32_IN_MEMORY 0 /* default = 0 */
-
-
-/*
- * Method used to read the input and write the output.
- * WARNING: non-portable code if set; might not work on all platforms.
- *
- * Twofish operates on 32-bit words. The input to the cipher is
- * a byte array, as is the output. The portable method of doing the
- * conversion is a bunch of rotate and mask operations, but on many
- * platforms it can be done faster using a cast.
- * This only works if your CPU allows UInt32 accesses to arbitrary Byte
- * addresses.
- *
- * Set to 0 to use the shift and mask operations. This is fully
- * portable. .
- *
- * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a
- * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN
- * macro) the byte order in the UInt32 is swapped. The reverse is done
- * to write the output of the encryption/decryption. Make sure you set
- * the CPU_IS_BIG_ENDIAN flag appropriately.
- * This option does not work unless a UInt32 is exactly 32 bits.
- *
- * This macro only changes the reading/writing of the plaintext/ciphertext.
- * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which
- * a UInt32 is split into 4 bytes for the S-box selection.
- */
-#define CONVERT_USING_CASTS 0 /* default = 0 */
-
-
-/*
- * Endianness switch.
- * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or
- * CONVERT_USING_CASTS is set.
- *
- * Set to 1 on a big-endian machine, and to 0 on a little-endian machine.
- * Twofish uses the little-endian convention (least significant byte first)
- * and big-endian machines (using most significant byte first)
- * have to do a few conversions.
- *
- * CAUTION: This code has never been tested on a big-endian machine,
- * because I don't have access to one. Feedback appreciated.
- */
-#define CPU_IS_BIG_ENDIAN 0
-
-
-/*
- * Macro to reverse the order of the bytes in a UInt32.
- * Used to convert to little-endian on big-endian machines.
- * This macro is always tested, but only used in the encryption and
- * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN
- * are both set. In other words: this macro is only speed-critical if
- * both these flags have been set.
- *
- * This default definition of SWAP works, but on many platforms there is a
- * more efficient implementation.
- */
-#define BSWAP(x) ((ROL32((x),8)&0x00ff00ff) | (ROR32((x),8) & 0xff00ff00))
-
-
-/*
- * END OF PLATFORM FIXES
- * =====================
- *
- * You should not have to touch the rest of this file.
- */
-
-
-/*
- * Convert the external type names to some that are easier to use inside
- * this file. I didn't want to use the names Byte and UInt32 in the
- * header file, because many programs already define them and using two
- * conventions at once can be very difficult.
- * Don't change these definitions! Change the originals
- * in twofish.h instead.
- */
-/* A Byte must be an unsigned integer, 8 bits long. */
-/* typedef Twofish_Byte Byte; */
-/* A UInt32 must be an unsigned integer at least 32 bits long. */
-/* typedef Twofish_UInt32 UInt32; */
-
-
-/*
- * Define a macro ENDIAN_CONVERT.
- *
- * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian
- * machines, and is the identity function on little-endian machines.
- * The code then uses this macro without considering the endianness.
- */
-
-#if CPU_IS_BIG_ENDIAN
-#define ENDIAN_CONVERT(x) BSWAP(x)
-#else
-#define ENDIAN_CONVERT(x) (x)
-#endif
-
-
-/*
- * Compute byte offset within a UInt32 stored in memory.
- *
- * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set.
- *
- * The input is the byte number 0..3, 0 for least significant.
- * Note the use of sizeof() to support UInt32 types that are larger
- * than 4 bytes.
- */
-#if CPU_IS_BIG_ENDIAN
-#define BYTE_OFFSET( n ) (sizeof(Twofish_UInt32) - 1 - (n) )
-#else
-#define BYTE_OFFSET( n ) (n)
-#endif
-
-
-/*
- * Macro to get Byte no. b from UInt32 value X.
- * We use two different definition, depending on the settings.
- */
-#if SELECT_BYTE_FROM_UINT32_IN_MEMORY
- /* Pick the byte from the memory in which X is stored. */
-#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)])
-#else
- /* Portable solution: Pick the byte directly from the X value. */
-#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff)
-#endif
-
-
-/* Some shorthands because we use byte selection in large formulae. */
-#define b0(X) SELECT_BYTE((X),0)
-#define b1(X) SELECT_BYTE((X),1)
-#define b2(X) SELECT_BYTE((X),2)
-#define b3(X) SELECT_BYTE((X),3)
-
-
-/*
- * We need macros to load and store UInt32 from/to byte arrays
- * using the least-significant-byte-first convention.
- *
- * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to
- * by p.
- * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form.
- */
-#if CONVERT_USING_CASTS
-
- /* Get UInt32 from four bytes pointed to by p. */
-#define GET32( p ) ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) )
- /* Put UInt32 into four bytes pointed to by p */
-#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v)
-
-#else
-
- /* Get UInt32 from four bytes pointed to by p. */
-#define GET32( p ) \
- ( \
- (Twofish_UInt32)((p)[0]) \
- | (Twofish_UInt32)((p)[1])<< 8 \
- | (Twofish_UInt32)((p)[2])<<16 \
- | (Twofish_UInt32)((p)[3])<<24 \
- )
- /* Put UInt32 into four bytes pointed to by p */
-#define PUT32( v, p ) \
- (p)[0] = (Twofish_Byte)(((v) ) & 0xff); \
- (p)[1] = (Twofish_Byte)(((v) >> 8) & 0xff); \
- (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \
- (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)
-
-#endif
-
-#ifdef ANDROID
-/**
- * Dummy function to disable some compiler optimizations.
- *
- * See comment in Twofish_cfb128_encrypt().
- */
-void Two_debugDummy(Twofish_Byte* in, Twofish_Byte* out, Twofish_Byte* ivec)
-{
-}
-#endif
-/*
- * Test the platform-specific macros.
- * This function tests the macros defined so far to make sure the
- * definitions are appropriate for this platform.
- * If you make any mistake in the platform configuration, this should detect
- * that and inform you what went wrong.
- * Somewhere, someday, this is going to save somebody a lot of time,
- * because misbehaving macros are hard to debug.
- */
-static int test_platform()
- {
- /* Buffer with test values. */
- Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0};
- Twofish_UInt32 C;
- Twofish_UInt32 x,y;
- int i;
-
- /*
- * Some sanity checks on the types that can't be done in compile time.
- * A smart compiler will just optimise these tests away.
- * The pre-processor doesn't understand different types, so we cannot
- * do these checks in compile-time.
- *
- * I hate C.
- *
- * The first check in each case is to make sure the size is correct.
- * The second check is to ensure that it is an unsigned type.
- */
- if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 ))
- {
- Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable", ERR_UINT32 );
- }
- if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) )
- {
- Twofish_fatal( "Twofish code: Twofish_Byte type not suitable", ERR_BYTE );
- }
-
- /*
- * Sanity-check the endianness conversions.
- * This is just an aid to find problems. If you do the endianness
- * conversion macros wrong you will fail the full cipher test,
- * but that does not help you find the error.
- * Always make it easy to find the bugs!
- *
- * Detail: There is no fully portable way of writing UInt32 constants,
- * as you don't know whether to use the U or UL suffix. Using only U you
- * might only be allowed 16-bit constants. Using UL you might get 64-bit
- * constants which cannot be stored in a UInt32 without warnings, and
- * which generally behave subtly different from a true UInt32.
- * As long as we're just comparing with the constant,
- * we can always use the UL suffix and at worst lose some efficiency.
- * I use a separate '32-bit constant' macro in most of my other code.
- *
- * I hate C.
- *
- * Start with testing GET32. We test it on all positions modulo 4
- * to make sure we can handly any position of inputs. (Some CPUs
- * do not allow non-aligned accesses which we would do if you used
- * the CONVERT_USING_CASTS option.
- */
- if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL)
- || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) )
- {
- Twofish_fatal( "Twofish code: GET32 not implemented properly", ERR_GET32 );
- }
-
- /*
- * We can now use GET32 to test PUT32.
- * We don't test the shifted versions. If GET32 can do that then
- * so should PUT32.
- */
- C = GET32( buf );
- PUT32( 3*C, buf );
- if( GET32( buf ) != 0x69029c36UL )
- {
- Twofish_fatal( "Twofish code: PUT32 not implemented properly", ERR_PUT32 );
- }
-
-
- /* Test ROL and ROR */
- for( i=1; i<32; i++ )
- {
- /* Just a simple test. */
- x = ROR32( C, i );
- y = ROL32( C, i );
- x ^= (C>>i) ^ (C<<(32-i));
- /*y ^= (C<>(32-i)); */
- y ^= (C<<i) ^ (C>>(32-i));
- x |= y;
- /*
- * Now all we check is that x is zero in the least significant
- * 32 bits. Using the UL suffix is safe here, as it doesn't matter
- * if we get a larger type.
- */
- if( (x & 0xffffffffUL) != 0 )
- {
- Twofish_fatal( "Twofish ROL or ROR not properly defined.", ERR_ROLR );
- }
- }
-
- /* Test the BSWAP macro */
- if( BSWAP(C) != 0x12345678UL )
- {
- /*
- * The BSWAP macro should always work, even if you are not using it.
- * A smart optimising compiler will just remove this entire test.
- */
- Twofish_fatal( "BSWAP not properly defined.", ERR_BSWAP );
- }
-
- /* And we can test the b macros which use SELECT_BYTE. */
- if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) )
- {
- /*
- * There are many reasons why this could fail.
- * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value.
- */
- Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly", ERR_SELECTB );
- }
- return SUCCESS;
- }
-
-
-/*
- * Finally, we can start on the Twofish-related code.
- * You really need the Twofish specifications to understand this code. The
- * best source is the Twofish book:
- * "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey,
- * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson.
- * you can also use the AES submission document of Twofish, which is
- * available from my list of publications on my personal web site at
- * http://niels.ferguson.net/.
- *
- * The first thing we do is write the testing routines. This is what the
- * implementation has to satisfy in the end. We only test the external
- * behaviour of the implementation of course.
- */
-
-
-/*
- * Perform a single self test on a (plaintext,ciphertext,key) triple.
- * Arguments:
- * key array of key bytes
- * key_len length of key in bytes
- * p plaintext
- * c ciphertext
- */
-static int test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] )
- {
- Twofish_Byte tmp[16]; /* scratch pad. */
- Twofish_key xkey; /* The expanded key */
- int i;
-
-
- /* Prepare the key */
- if ((i = Twofish_prepare_key( key, key_len, &xkey)) < 0)
- return i;
-
- /*
- * We run the test twice to ensure that the xkey structure
- * is not damaged by the first encryption.
- * Those are hideous bugs to find if you get them in an application.
- */
- for( i=0; i<2; i++ )
- {
- /* Encrypt and test */
- Twofish_encrypt( &xkey, p, tmp );
- if( memcmp( c, tmp, 16 ) != 0 )
- {
- Twofish_fatal( "Twofish encryption failure", ERR_TEST_ENC );
- }
-
- /* Decrypt and test */
- Twofish_decrypt( &xkey, c, tmp );
- if( memcmp( p, tmp, 16 ) != 0 )
- {
- Twofish_fatal( "Twofish decryption failure", ERR_TEST_DEC );
- }
- }
-
- /* The test keys are not secret, so we don't need to wipe xkey. */
- return SUCCESS;
- }
-
-
-/*
- * Check implementation using three (key,plaintext,ciphertext)
- * test vectors, one for each major key length.
- *
- * This is an absolutely minimal self-test.
- * This routine does not test odd-sized keys.
- */
-static int test_vectors()
- {
- /*
- * We run three tests, one for each major key length.
- * These test vectors come from the Twofish specification.
- * One encryption and one decryption using randomish data and key
- * will detect almost any error, especially since we generate the
- * tables ourselves, so we don't have the problem of a single
- * damaged table entry in the source.
- */
-
- /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */
- static Twofish_Byte k128[] = {
- 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
- 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A,
- };
- static Twofish_Byte p128[] = {
- 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
- 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
- };
- static Twofish_Byte c128[] = {
- 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
- 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
- };
-
- /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */
- static Twofish_Byte k192[] = {
- 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
- 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
- 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44
- };
- static Twofish_Byte p192[] = {
- 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
- 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2
- };
- static Twofish_Byte c192[] = {
- 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
- 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65
- };
-
- /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */
- static Twofish_Byte k256[] = {
- 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
- 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
- 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
- 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
- };
- static Twofish_Byte p256[] = {
- 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
- 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
- };
- static Twofish_Byte c256[] = {
- 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
- 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
- };
-
- int ret;
-
- /* Run the actual tests. */
- if ((ret = test_vector( k128, 16, p128, c128 )) < 0)
- return ret;
- if ((ret = test_vector( k192, 24, p192, c192 )) < 0)
- return ret;
- if ((ret = test_vector( k256, 32, p256, c256 )) < 0)
- return ret;
- return SUCCESS;
- }
-
-
-/*
- * Perform extensive test for a single key size.
- *
- * Test a single key size against the test vectors from section
- * B.2 in the Twofish book. This is a sequence of 49 encryptions
- * and decryptions. Each plaintext is equal to the ciphertext of
- * the previous encryption. The key is made up from the ciphertext
- * two and three encryptions ago. Both plaintext and key start
- * at the zero value.
- * We should have designed a cleaner recurrence relation for
- * these tests, but it is too late for that now. At least we learned
- * how to do it better next time.
- * For details see appendix B of the book.
- *
- * Arguments:
- * key_len Number of bytes of key
- * final_value Final plaintext value after 49 iterations
- */
-static int test_sequence( int key_len, Twofish_Byte final_value[] )
- {
- Twofish_Byte buf[ (50+3)*16 ]; /* Buffer to hold our computation values. */
- Twofish_Byte tmp[16]; /* Temp for testing the decryption. */
- Twofish_key xkey; /* The expanded key */
- int i, ret;
- Twofish_Byte * p;
-
- /* Wipe the buffer */
- memset( buf, 0, sizeof( buf ) );
-
- /*
- * Because the recurrence relation is done in an inconvenient manner
- * we end up looping backwards over the buffer.
- */
-
- /* Pointer in buffer points to current plaintext. */
- p = &buf[50*16];
- for( i=1; i<50; i++ )
- {
- /*
- * Prepare a key.
- * This automatically checks that key_len is valid.
- */
- if ((ret = Twofish_prepare_key( p+16, key_len, &xkey)) < 0)
- return ret;
-
- /* Compute the next 16 bytes in the buffer */
- Twofish_encrypt( &xkey, p, p-16 );
-
- /* Check that the decryption is correct. */
- Twofish_decrypt( &xkey, p-16, tmp );
- if( memcmp( tmp, p, 16 ) != 0 )
- {
- Twofish_fatal( "Twofish decryption failure in sequence", ERR_SEQ_DEC );
- }
- /* Move on to next 16 bytes in the buffer. */
- p -= 16;
- }
-
- /* And check the final value. */
- if( memcmp( p, final_value, 16 ) != 0 )
- {
- Twofish_fatal( "Twofish encryption failure in sequence", ERR_SEQ_ENC );
- }
-
- /* None of the data was secret, so there is no need to wipe anything. */
- return SUCCESS;
- }
-
-
-/*
- * Run all three sequence tests from the Twofish test vectors.
- *
- * This checks the most extensive test vectors currently available
- * for Twofish. The data is from the Twofish book, appendix B.2.
- */
-static int test_sequences()
- {
- static Twofish_Byte r128[] = {
- 0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57,
- 0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0
- };
- static Twofish_Byte r192[] = {
- 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4,
- 0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41
- };
- static Twofish_Byte r256[] = {
- 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75,
- 0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05
- };
-
- /* Run the three sequence test vectors */
- int ret;
- if ((ret = test_sequence( 16, r128)) < 0)
- return ret;
- if ((ret = test_sequence( 24, r192)) < 0)
- return ret;
- if ((ret = test_sequence( 32, r256)) < 0)
- return ret;
- return SUCCESS;
- }
-
-
-/*
- * Test the odd-sized keys.
- *
- * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits.
- * The equivalent key is found by padding at the end with zero bytes
- * until a regular key size is reached.
- *
- * We just test that the key expansion routine behaves properly.
- * If the expanded keys are identical, then the encryptions and decryptions
- * will behave the same.
- */
-static int test_odd_sized_keys()
- {
- Twofish_Byte buf[32];
- Twofish_key xkey;
- Twofish_key xkey_two;
- int i, ret;
-
- /*
- * We first create an all-zero key to use as PRNG key.
- * Normally we would not have to fill the buffer with zeroes, as we could
- * just pass a zero key length to the Twofish_prepare_key function.
- * However, this relies on using odd-sized keys, and those are just the
- * ones we are testing here. We can't use an untested function to test
- * itself.
- */
- memset( buf, 0, sizeof( buf ) );
- if ((ret = Twofish_prepare_key( buf, 16, &xkey)) < 0)
- return ret;
-
- /* Fill buffer with pseudo-random data derived from two encryptions */
- Twofish_encrypt( &xkey, buf, buf );
- Twofish_encrypt( &xkey, buf, buf+16 );
-
- /* Create all possible shorter keys that are prefixes of the buffer. */
- for( i=31; i>=0; i-- )
- {
- /* Set a byte to zero. This is the new padding byte */
- buf[i] = 0;
-
- /* Expand the key with only i bytes of length */
- if ((ret = Twofish_prepare_key( buf, i, &xkey)) < 0)
- return ret;
-
- /* Expand the corresponding padded key of regular length */
- if ((ret = Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two )) < 0)
- return ret;
-
- /* Compare the two */
- if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 )
- {
- Twofish_fatal( "Odd sized keys do not expand properly", ERR_ODD_KEY );
- }
- }
-
- /* None of the key values are secret, so we don't need to wipe them. */
- return SUCCESS;
- }
-
-
-/*
- * Test the Twofish implementation.
- *
- * This routine runs all the self tests, in order of importance.
- * It is called by the Twofish_initialise routine.
- *
- * In almost all applications the cost of running the self tests during
- * initialisation is insignificant, especially
- * compared to the time it takes to load the application from disk.
- * If you are very pressed for initialisation performance,
- * you could remove some of the tests. Make sure you did run them
- * once in the software and hardware configuration you are using.
- */
-static int self_test()
- {
- int ret;
- /* The three test vectors form an absolute minimal test set. */
- if ((ret = test_vectors()) < 0)
- return ret;
-
- /*
- * If at all possible you should run these tests too. They take
- * more time, but provide a more thorough coverage.
- */
- if ((ret = test_sequences()) < 0)
- return ret;
-
- /* Test the odd-sized keys. */
- if ((ret = test_odd_sized_keys()) < 0)
- return ret;
- return SUCCESS;
- }
-
-
-/*
- * And now, the actual Twofish implementation.
- *
- * This implementation generates all the tables during initialisation.
- * I don't like large tables in the code, especially since they are easily
- * damaged in the source without anyone noticing it. You need code to
- * generate them anyway, and this way all the code is close together.
- * Generating them in the application leads to a smaller executable
- * (the code is smaller than the tables it generates) and a
- * larger static memory footprint.
- *
- * Twofish can be implemented in many ways. I have chosen to
- * use large tables with a relatively long key setup time.
- * If you encrypt more than a few blocks of data it pays to pre-compute
- * as much as possible. This implementation is relatively inefficient for
- * applications that need to re-key every block or so.
- */
-
-/*
- * We start with the t-tables, directly from the Twofish definition.
- * These are nibble-tables, but merging them and putting them two nibbles
- * in one byte is more work than it is worth.
- */
-static Twofish_Byte t_table[2][4][16] = {
- {
- {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4},
- {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD},
- {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1},
- {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA}
- },
- {
- {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5},
- {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8},
- {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF},
- {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA}
- }
-};
-
-
-/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */
-#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) )
-
-/*
- * The q-boxes are only used during the key schedule computations.
- * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit
- * lookup tables as it is faster to load a 32-bit value than to load an
- * 8-bit value and zero the rest of the register.
- * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in
- * the q-tables. Here we just define the Qtype which is used to store
- * the entries of the q-tables.
- */
-#if LARGE_Q_TABLE
-typedef Twofish_UInt32 Qtype;
-#else
-typedef Twofish_Byte Qtype;
-#endif
-
-/*
- * The actual q-box tables.
- * There are two q-boxes, each having 256 entries.
- */
-static Qtype q_table[2][256];
-
-
-/*
- * Now the function that converts a single t-table into a q-table.
- *
- * Arguments:
- * t[4][16] : four 4->4bit lookup tables that define the q-box
- * q[256] : output parameter: the resulting q-box as a lookup table.
- */
-static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] )
- {
- int ae,be,ao,bo; /* Some temporaries. */
- int i;
- /* Loop over all input values and compute the q-box result. */
- for( i=0; i<256; i++ ) {
- /*
- * This is straight from the Twofish specifications.
- *
- * The ae variable is used for the a_i values from the specs
- * with even i, and ao for the odd i's. Similarly for the b's.
- */
- ae = i>>4; be = i&0xf;
- ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
- ae = t[0][ao]; be = t[1][bo];
- ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
- ae = t[2][ao]; be = t[3][bo];
-
- /* Store the result in the q-box table, the cast avoids a warning. */
- q[i] = (Qtype) ((be<<4) | ae);
- }
- }
-
-
-/*
- * Initialise both q-box tables.
- */
-static void initialise_q_boxes() {
- /* Initialise each of the q-boxes using the t-tables */
- make_q_table( t_table[0], q_table[0] );
- make_q_table( t_table[1], q_table[1] );
- }
-
-
-/*
- * Next up is the MDS matrix multiplication.
- * The MDS matrix multiplication operates in the field
- * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1.
- * If you don't understand this, read a book on finite fields. You cannot
- * follow the finite-field computations without some background.
- *
- * In this field, multiplication by x is easy: shift left one bit
- * and if bit 8 is set then xor the result with 0x169.
- *
- * The MDS coefficients use a multiplication by 1/x,
- * or rather a division by x. This is easy too: first make the
- * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary,
- * and then shift right one position.
- * Even easier: shift right and xor with 0xb4 if the lsbit was set.
- *
- * The MDS coefficients are 1, EF, and 5B, and we use the fact that
- * EF = 1 + 1/x + 1/x^2
- * 5B = 1 + 1/x^2
- * in this field. This makes multiplication by EF and 5B relatively easy.
- *
- * This property is no accident, the MDS matrix was designed to allow
- * this implementation technique to be used.
- *
- * We have four MDS tables, each mapping 8 bits to 32 bits.
- * Each table performs one column of the matrix multiplication.
- * As the MDS is always preceded by q-boxes, each of these tables
- * also implements the q-box just previous to that column.
- */
-
-/* The actual MDS tables. */
-static Twofish_UInt32 MDS_table[4][256];
-
-/* A small table to get easy conditional access to the 0xb4 constant. */
-static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4};
-
-/* Function to initialise the MDS tables. */
-static void initialise_mds_tables()
- {
- int i;
- Twofish_UInt32 q,qef,q5b; /* Temporary variables. */
-
- /* Loop over all 8-bit input values */
- for( i=0; i<256; i++ )
- {
- /*
- * To save some work during the key expansion we include the last
- * of the q-box layers from the h() function in these MDS tables.
- */
-
- /* We first do the inputs that are mapped through the q0 table. */
- q = q_table[0][i];
- /*
- * Here we divide by x, note the table to get 0xb4 only if the
- * lsbit is set.
- * This sets qef = (1/x)*q in the finite field
- */
- qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
- /*
- * Divide by x again, and add q to get (1+1/x^2)*q.
- * Note that (1+1/x^2) = 5B in the field, and addition in the field
- * is exclusive or on the bits.
- */
- q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
- /*
- * Add q5b to qef to set qef = (1+1/x+1/x^2)*q.
- * Again, (1+1/x+1/x^2) = EF in the field.
- */
- qef ^= q5b;
-
- /*
- * Now that we have q5b = 5B * q and qef = EF * q
- * we can fill two of the entries in the MDS matrix table.
- * See the Twofish specifications for the order of the constants.
- */
- MDS_table[1][i] = (q <<24) | (q5b<<16) | (qef<<8) | qef;
- MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q <<8) | q5b;
-
- /* Now we do it all again for the two columns that have a q1 box. */
- q = q_table[1][i];
- qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
- q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
- qef ^= q5b;
-
- /* The other two columns use the coefficient in a different order. */
- MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q ;
- MDS_table[2][i] = (qef<<24) | (q <<16) | (qef<<8) | q5b;
- }
- }
-
-
-/*
- * The h() function is the heart of the Twofish cipher.
- * It is a complicated sequence of q-box lookups, key material xors,
- * and finally the MDS matrix.
- * We use lots of macros to make this reasonably fast.
- */
-
-/* First a shorthand for the two q-tables */
-#define q0 q_table[0]
-#define q1 q_table[1]
-
-/*
- * Each macro computes one column of the h for either 2, 3, or 4 stages.
- * As there are 4 columns, we have 12 macros in all.
- *
- * The key bytes are stored in the Byte array L at offset
- * 0,1,2,3, 8,9,10,11, [16,17,18,19, [24,25,26,27]] as this is the
- * order we get the bytes from the user. If you look at the Twofish
- * specs, you'll see that h() is applied to the even key words or the
- * odd key words. The bytes of the even words appear in this spacing,
- * and those of the odd key words too.
- *
- * These macros are the only place where the q-boxes and the MDS table
- * are used.
- */
-#define H02( y, L ) MDS_table[0][q0[q0[y]^L[ 8]]^L[0]]
-#define H12( y, L ) MDS_table[1][q0[q1[y]^L[ 9]]^L[1]]
-#define H22( y, L ) MDS_table[2][q1[q0[y]^L[10]]^L[2]]
-#define H32( y, L ) MDS_table[3][q1[q1[y]^L[11]]^L[3]]
-#define H03( y, L ) H02( q1[y]^L[16], L )
-#define H13( y, L ) H12( q1[y]^L[17], L )
-#define H23( y, L ) H22( q0[y]^L[18], L )
-#define H33( y, L ) H32( q0[y]^L[19], L )
-#define H04( y, L ) H03( q1[y]^L[24], L )
-#define H14( y, L ) H13( q0[y]^L[25], L )
-#define H24( y, L ) H23( q0[y]^L[26], L )
-#define H34( y, L ) H33( q1[y]^L[27], L )
-
-/*
- * Now we can define the h() function given an array of key bytes.
- * This function is only used in the key schedule, and not to pre-compute
- * the keyed S-boxes.
- *
- * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24)
- * so we only provide k as an argument.
- *
- * Arguments:
- * k input to the h() function.
- * L pointer to array of key bytes at
- * offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]]
- * kCycles # key cycles, 2, 3, or 4.
- */
-static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles )
- {
- switch( kCycles ) {
- /* We code all 3 cases separately for speed reasons. */
- case 2:
- return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L);
- case 3:
- return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L);
- case 4:
- return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L);
- default:
- /* This is always a coding error, which is fatal. */
- Twofish_fatal( "Twofish h(): Illegal argument", ERR_ILL_ARG );
- return ERR_ILL_ARG;
- }
- }
-
-
-/*
- * Pre-compute the keyed S-boxes.
- * Fill the pre-computed S-box array in the expanded key structure.
- * Each pre-computed S-box maps 8 bits to 32 bits.
- *
- * The S argument contains half the number of bytes of the full key, but is
- * derived from the full key. (See Twofish specifications for details.)
- * S has the weird byte input order used by the Hxx macros.
- *
- * This function takes most of the time of a key expansion.
- *
- * Arguments:
- * S pointer to array of 8*kCycles Bytes containing the S vector.
- * kCycles number of key words, must be in the set {2,3,4}
- * xkey pointer to Twofish_key structure that will contain the S-boxes.
- */
-static int fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey )
- {
- int i;
- switch( kCycles ) {
- /* We code all 3 cases separately for speed reasons. */
- case 2:
- for( i=0; i<256; i++ )
- {
- xkey->s[0][i]= H02( i, S );
- xkey->s[1][i]= H12( i, S );
- xkey->s[2][i]= H22( i, S );
- xkey->s[3][i]= H32( i, S );
- }
- break;
- case 3:
- for( i=0; i<256; i++ )
- {
- xkey->s[0][i]= H03( i, S );
- xkey->s[1][i]= H13( i, S );
- xkey->s[2][i]= H23( i, S );
- xkey->s[3][i]= H33( i, S );
- }
- break;
- case 4:
- for( i=0; i<256; i++ )
- {
- xkey->s[0][i]= H04( i, S );
- xkey->s[1][i]= H14( i, S );
- xkey->s[2][i]= H24( i, S );
- xkey->s[3][i]= H34( i, S );
- }
- break;
- default:
- /* This is always a coding error, which is fatal. */
- Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument", ERR_ILL_ARG );
- }
- return SUCCESS;
- }
-
-
-/* A flag to keep track of whether we have been initialised or not. */
-static int Twofish_initialised = 0;
-
-/*
- * Initialise the Twofish implementation.
- * This function must be called before any other function in the
- * Twofish implementation is called.
- * This routine also does some sanity checks, to make sure that
- * all the macros behave, and it tests the whole cipher.
- */
-int Twofish_initialise()
- {
- int ret;
- /* First test the various platform-specific definitions. */
- if ((ret = test_platform()) < 0)
- return ret;
-
- /* We can now generate our tables, in the right order of course. */
- initialise_q_boxes();
- initialise_mds_tables();
-
- /* We're finished with the initialisation itself. */
- Twofish_initialised = 1;
-
- /*
- * And run some tests on the whole cipher.
- * Yes, you need to do this every time you start your program.
- * It is called assurance; you have to be certain that your program
- * still works properly.
- */
- return self_test();
- }
-
-
-/*
- * The Twofish key schedule uses an Reed-Solomon code matrix multiply.
- * Just like the MDS matrix, the RS-matrix is designed to be easy
- * to implement. Details are below in the code.
- *
- * These constants make it easy to compute in the finite field used
- * for the RS code.
- *
- * We use Bytes for the RS computation, but these are automatically
- * widened to unsigned integers in the expressions. Having unsigned
- * ints in these tables therefore provides the fastest access.
- */
-static unsigned int rs_poly_const[] = {0, 0x14d};
-static unsigned int rs_poly_div_const[] = {0, 0xa6 };
-
-
-/*
- * Prepare a key for use in encryption and decryption.
- * Like most block ciphers, Twofish allows the key schedule
- * to be pre-computed given only the key.
- * Twofish has a fairly 'heavy' key schedule that takes a lot of time
- * to compute. The main work is pre-computing the S-boxes used in the
- * encryption and decryption. We feel that this makes the cipher much
- * harder to attack. The attacker doesn't even know what the S-boxes
- * contain without including the entire key schedule in the analysis.
- *
- * Unlike most Twofish implementations, this one allows any key size from
- * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the
- * specifications); the key is simply padded with zeroes to the next real
- * key size of 16, 24, or 32 bytes.
- * Each odd-sized key is thus equivalent to a single normal-sized key.
- *
- * Arguments:
- * key array of key bytes
- * key_len number of bytes in the key, must be in the range 0,...,32.
- * xkey Pointer to an Twofish_key structure that will be filled
- * with the internal form of the cipher key.
- */
-int Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey )
- {
- /* We use a single array to store all key material in,
- * to simplify the wiping of the key material at the end.
- * The first 32 bytes contain the actual (padded) cipher key.
- * The next 32 bytes contain the S-vector in its weird format,
- * and we have 4 bytes of overrun necessary for the RS-reduction.
- */
- Twofish_Byte K[32+32+4];
-
- int kCycles; /* # key cycles, 2,3, or 4. */
-
- int i;
- Twofish_UInt32 A, B; /* Used to compute the round keys. */
-
- Twofish_Byte * kptr; /* Three pointers for the RS computation. */
- Twofish_Byte * sptr;
- Twofish_Byte * t;
-
- Twofish_Byte b,bx,bxx; /* Some more temporaries for the RS computation. */
-
- /* Check that the Twofish implementation was initialised. */
- if( Twofish_initialised == 0 )
- {
- /*
- * You didn't call Twofish_initialise before calling this routine.
- * This is a programming error, and therefore we call the fatal
- * routine.
- *
- * I could of course call the initialisation routine here,
- * but there are a few reasons why I don't. First of all, the
- * self-tests have to be done at startup. It is no good to inform
- * the user that the cipher implementation fails when he wants to
- * write his data to disk in encrypted form. You have to warn him
- * before he spends time typing his data. Second, the initialisation
- * and self test are much slower than a single key expansion.
- * Calling the initialisation here makes the performance of the
- * cipher unpredictable. This can lead to really weird problems
- * if you use the cipher for a real-time task. Suddenly it fails
- * once in a while the first time you try to use it. Things like
- * that are almost impossible to debug.
- */
- /* Twofish_fatal( "Twofish implementation was not initialised.", ERR_INIT ); */
-
- /*
- * There is always a danger that the Twofish_fatal routine returns,
- * in spite of the specifications that it should not.
- * (A good programming rule: don't trust the rest of the code.)
- * This would be disasterous. If the q-tables and MDS-tables have
- * not been initialised, they are probably still filled with zeroes.
- * Suppose the MDS-tables are all zero. The key expansion would then
- * generate all-zero round keys, and all-zero s-boxes. The danger
- * is that nobody would notice as the encry
- * mangles the input, and the decryption still 'decrypts' it,
- * but now in a completely key-independent manner.
- * To stop such security disasters, we use blunt force.
- * If your program hangs here: fix the fatal routine!
- */
- for(;;); /* Infinite loop, which beats being insecure. */
- }
-
- /* Check for valid key length. */
- if( key_len < 0 || key_len > 32 )
- {
- /*
- * This can only happen if a programmer didn't read the limitations
- * on the key size.
- */
- Twofish_fatal( "Twofish_prepare_key: illegal key length", ERR_KEY_LEN );
- /*
- * A return statement just in case the fatal macro returns.
- * The rest of the code assumes that key_len is in range, and would
- * buffer-overflow if it wasn't.
- *
- * Why do we still use a programming language that has problems like
- * buffer overflows, when these problems were solved in 1960 with
- * the development of Algol? Have we not leared anything?
- */
- return ERR_KEY_LEN;
- }
-
- /* Pad the key with zeroes to the next suitable key length. */
- memcpy( K, key, key_len );
- memset( K+key_len, 0, sizeof(K)-key_len );
-
- /*
- * Compute kCycles: the number of key cycles used in the cipher.
- * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys.
- */
- kCycles = (key_len + 7) >> 3;
- /* Handle the special case of very short keys: minimum 2 cycles. */
- if( kCycles < 2 )
- {
- kCycles = 2;
- }
-
- /*
- * From now on we just pretend to have 8*kCycles bytes of
- * key material in K. This handles all the key size cases.
- */
-
- /*
- * We first compute the 40 expanded key words,
- * formulas straight from the Twofish specifications.
- */
- for( i=0; i<40; i+=2 )
- {
- /*
- * Due to the byte spacing expected by the h() function
- * we can pick the bytes directly from the key K.
- * As we use bytes, we never have the little/big endian
- * problem.
- *
- * Note that we apply the rotation function only to simple
- * variables, as the rotation macro might evaluate its argument
- * more than once.
- */
- A = h( i , K , kCycles );
- B = h( i+1, K+4, kCycles );
- B = ROL32( B, 8 );
-
- /* Compute and store the round keys. */
- A += B;
- B += A;
- xkey->K[i] = A;
- xkey->K[i+1] = ROL32( B, 9 );
- }
-
- /* Wipe variables that contained key material. */
- A=B=0;
-
- /*
- * And now the dreaded RS multiplication that few seem to understand.
- * The RS matrix is not random, and is specially designed to compute the
- * RS matrix multiplication in a simple way.
- *
- * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a
- * different field than used for the MDS matrix.
- * (At least, it is a different representation because all GF(2^8)
- * representations are equivalent in some form.)
- *
- * We take 8 consecutive bytes of the key and interpret them as
- * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where
- * the k_i bytes are the key bytes and are elements of the finite field.
- * We multiply this polynomial by y^4 and reduce it modulo
- * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1.
- * using straightforward polynomial modulo reduction.
- * The coefficients of the result are the result of the RS
- * matrix multiplication. When we wrote the Twofish specification,
- * the original RS definition used the polynomials,
- * but that requires much more mathematical knowledge.
- * We were already using matrix multiplication in a finite field for
- * the MDS matrix, so I re-wrote the RS operation as a matrix
- * multiplication to reduce the difficulty of understanding it.
- * Some implementors have not picked up on this simpler method of
- * computing the RS operation, even though it is mentioned in the
- * specifications.
- *
- * It is possible to perform these computations faster by using 32-bit
- * word operations, but that is not portable and this is not a speed-
- * critical area.
- *
- * We explained the 1/x computation when we did the MDS matrix.
- *
- * The S vector is stored in K[32..64].
- * The S vector has to be reversed, so we loop cross-wise.
- *
- * Note the weird byte spacing of the S-vector, to match the even
- * or odd key words arrays. See the discussion at the Hxx macros for
- * details.
- */
- kptr = K + 8*kCycles; /* Start at end of key */
- sptr = K + 32; /* Start at start of S */
-
- /* Loop over all key material */
- while( kptr > K )
- {
- kptr -= 8;
- /*
- * Initialise the polynimial in sptr[0..12]
- * The first four coefficients are 0 as we have to multiply by y^4.
- * The next 8 coefficients are from the key material.
- */
- memset( sptr, 0, 4 );
- memcpy( sptr+4, kptr, 8 );
-
- /*
- * The 12 bytes starting at sptr are now the coefficients of
- * the polynomial we need to reduce.
- */
-
- /* Loop over the polynomial coefficients from high to low */
- t = sptr+11;
- /* Keep looping until polynomial is degree 3; */
- while( t > sptr+3 )
- {
- /* Pick up the highest coefficient of the poly. */
- b = *t;
-
- /*
- * Compute x and (x+1/x) times this coefficient.
- * See the MDS matrix implementation for a discussion of
- * multiplication by x and 1/x. We just use different
- * constants here as we are in a
- * different finite field representation.
- *
- * These two statements set
- * bx = (x) * b
- * bxx= (x + 1/x) * b
- */
- bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]);
- bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx);
-
- /*
- * Subtract suitable multiple of
- * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1
- * from the polynomial, except that we don't bother
- * updating t[0] as it will become zero anyway.
- */
- t[-1] ^= bxx;
- t[-2] ^= bx;
- t[-3] ^= bxx;
- t[-4] ^= b;
-
- /* Go to the next coefficient. */
- t--;
- }
-
- /* Go to next S-vector word, obeying the weird spacing rules. */
- sptr += 8;
- }
-
- /* Wipe variables that contained key material. */
- b = bx = bxx = 0;
-
- /* And finally, we can compute the key-dependent S-boxes. */
- fill_keyed_sboxes( &K[32], kCycles, xkey );
-
- /* Wipe array that contained key material. */
- memset( K, 0, sizeof( K ) );
- return SUCCESS;
- }
-
-
-/*
- * We can now start on the actual encryption and decryption code.
- * As these are often speed-critical we will use a lot of macros.
- */
-
-/*
- * The g() function is the heart of the round function.
- * We have two versions of the g() function, one without an input
- * rotation and one with.
- * The pre-computed S-boxes make this pretty simple.
- */
-#define g0(X,xkey) \
- (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)])
-
-#define g1(X,xkey) \
- (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)])
-
-/*
- * A single round of Twofish. The A,B,C,D are the four state variables,
- * T0 and T1 are temporaries, xkey is the expanded key, and r the
- * round number.
- *
- * Note that this macro does not implement the swap at the end of the round.
- */
-#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
- T0 = g0(A,xkey); T1 = g1(B,xkey);\
- C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\
- D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1]
-
-/*
- * Encrypt a single cycle, consisting of two rounds.
- * This avoids the swapping of the two halves.
- * Parameter r is now the cycle number.
- */
-#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
- ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r) );\
- ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 )
-
-/* Full 16-round encryption */
-#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
- ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 )
-
-/*
- * A single round of Twofish for decryption. It differs from
- * ENCRYTP_RND only because of the 1-bit rotations.
- */
-#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
- T0 = g0(A,xkey); T1 = g1(B,xkey);\
- C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\
- D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1)
-
-/*
- * Decrypt a single cycle, consisting of two rounds.
- * This avoids the swapping of the two halves.
- * Parameter r is now the cycle number.
- */
-#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
- DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\
- DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r) )
-
-/* Full 16-round decryption. */
-#define DECRYPT( A,B,C,D,T0,T1, xkey ) \
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
- DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 )
-
-/*
- * A macro to read the state from the plaintext and do the initial key xors.
- * The koff argument allows us to use the same macro
- * for the decryption which uses different key words at the start.
- */
-#define GET_INPUT( src, A,B,C,D, xkey, koff ) \
- A = GET32(src )^xkey->K[ koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \
- C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff]
-
-/*
- * Similar macro to put the ciphertext in the output buffer.
- * We xor the keys into the state variables before we use the PUT32
- * macro as the macro might use its argument multiple times.
- */
-#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \
- A ^= xkey->K[ koff]; B ^= xkey->K[1+koff]; \
- C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \
- PUT32( A, dst ); PUT32( B, dst+ 4 ); \
- PUT32( C, dst+8 ); PUT32( D, dst+12 )
-
-
-/*
- * Twofish block encryption
- *
- * Arguments:
- * xkey expanded key array
- * p 16 bytes of plaintext
- * c 16 bytes in which to store the ciphertext
- */
-void Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16])
- {
- Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */
-
- /* Get the four plaintext words xorred with the key */
- GET_INPUT( p, A,B,C,D, xkey, 0 );
-
- /* Do 8 cycles (= 16 rounds) */
- ENCRYPT( A,B,C,D,T0,T1,xkey );
-
- /* Store them with the final swap and the output whitening. */
- PUT_OUTPUT( C,D,A,B, c, xkey, 4 );
- }
-
-
-/*
- * Twofish block decryption.
- *
- * Arguments:
- * xkey expanded key array
- * p 16 bytes of plaintext
- * c 16 bytes in which to store the ciphertext
- */
-void Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16])
- {
- Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */
-
- /* Get the four plaintext words xorred with the key */
- GET_INPUT( c, A,B,C,D, xkey, 4 );
-
- /* Do 8 cycles (= 16 rounds) */
- DECRYPT( A,B,C,D,T0,T1,xkey );
-
- /* Store them with the final swap and the output whitening. */
- PUT_OUTPUT( C,D,A,B, p, xkey, 0 );
- }
-
-/*
- * Using the macros it is easy to make special routines for
- * CBC mode, CTR mode etc. The only thing you might want to
- * add is a XOR_PUT_OUTPUT which xors the outputs into the
- * destinationa instead of overwriting the data. This requires
- * a XOR_PUT32 macro as well, but that should all be trivial.
- *
- * I thought about including routines for the separate cipher
- * modes here, but it is unclear which modes should be included,
- * and each encryption or decryption routine takes up a lot of code space.
- * Also, I don't have any test vectors for any cipher modes
- * with Twofish.
- */
-
-
+/*
+ * Fast, portable, and easy-to-use Twofish implementation,
+ * Version 0.3.
+ * Copyright (c) 2002 by Niels Ferguson.
+ * (See further down for the almost-unrestricted licensing terms.)
+ *
+ * --------------------------------------------------------------------------
+ * There are two files for this implementation:
+ * - twofish.h, the header file.
+ * - twofish.c, the code file.
+ *
+ * To incorporate this code into your program you should:
+ * - Check the licensing terms further down in this comment.
+ * - Fix the two type definitions in twofish.h to suit your platform.
+ * - Fix a few definitions in twofish.c in the section marked
+ * PLATFORM FIXES. There is one important ones that affects
+ * functionality, and then a few definitions that you can optimise
+ * for efficiency but those have no effect on the functionality.
+ * Don't change anything else.
+ * - Put the code in your project and compile it.
+ *
+ * To use this library you should:
+ * - Call Twofish_initialise() in your program before any other function in
+ * this library.
+ * - Use Twofish_prepare_key(...) to convert a key to internal form.
+ * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt
+ * data.
+ * See the comments in the header file for details on these functions.
+ * --------------------------------------------------------------------------
+ *
+ * There are many Twofish implementation available for free on the web.
+ * Most of them are hard to integrate into your own program.
+ * As we like people to use our cipher, I thought I would make it easier.
+ * Here is a free and easy-to-integrate Twofish implementation in C.
+ * The latest version is always available from my personal home page at
+ * http://niels.ferguson.net/
+ *
+ * Integrating library code into a project is difficult because the library
+ * header files interfere with the project's header files and code.
+ * And of course the project's header files interfere with the library code.
+ * I've tried to resolve these problems here.
+ * The header file of this implementation is very light-weight.
+ * It contains two typedefs, a structure, and a few function declarations.
+ * All names it defines start with "Twofish_".
+ * The header file is therefore unlikely to cause problems in your project.
+ * The code file of this implementation doesn't need to include the header
+ * files of the project. There is thus no danger of the project interfering
+ * with all the definitions and macros of the Twofish code.
+ * In most situations, all you need to do is fill in a few platform-specific
+ * definitions in the header file and code file,
+ * and you should be able to run the Twofish code in your project.
+ * I estimate it should take you less than an hour to integrate this code
+ * into your project, most of it spent reading the comments telling you what
+ * to do.
+ *
+ * For people using C++: it is very easy to wrap this library into a
+ * TwofishKey class. One of the big advantages is that you can automate the
+ * wiping of the key material in the destructor. I have not provided a C++
+ * class because the interface depends too much on the abstract base class
+ * you use for block ciphers in your program, which I don't know about.
+ *
+ * This implementation is designed for use on PC-class machines. It uses the
+ * Twofish 'full' keying option which uses large tables. Total table size is
+ * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key.
+ * If you need an implementation that uses less memory,
+ * take a look at Brian Gladman's code on his web site:
+ * http://fp.gladman.plus.com/cryptography_technology/aes/
+ * He has code for all AES candidates.
+ * His Twofish code has lots of options trading off table size vs. speed.
+ * You can also take a look at the optimised code by Doug Whiting on the
+ * Twofish web site
+ * http://www.counterpane.com/twofish.html
+ * which has loads of options.
+ * I believe these existing implementations are harder to re-use because they
+ * are not clean libraries and they impose requirements on the environment.
+ * This implementation is very careful to minimise those,
+ * and should be easier to integrate into any larger program.
+ *
+ * The default mode of this implementation is fully portable as it uses no
+ * behaviour not defined in the C standard. (This is harder than you think.)
+ * If you have any problems porting the default mode, please let me know
+ * so that I can fix the problem. (But only if this code is at fault, I
+ * don't fix compilers.)
+ * Most of the platform fixes are related to non-portable but faster ways
+ * of implementing certain functions.
+ *
+ * In general I've tried to make the code as fast as possible, at the expense
+ * of memory and code size. However, C does impose limits, and this
+ * implementation will be slower than an optimised assembler implementation.
+ * But beware of assembler implementations: a good Pentium implementation
+ * uses completely different code than a good Pentium II implementation.
+ * You basically have to re-write the assembly code for every generation of
+ * processor. Unless you are severely pressed for speed, stick with C.
+ *
+ * The initialisation routine of this implementation contains a self-test.
+ * If initialisation succeeds without calling the fatal routine, then
+ * the implementation works. I don't think you can break the implementation
+ * in such a way that it still passes the tests, unless you are malicious.
+ * In other words: if the initialisation routine returns,
+ * you have successfully ported the implementation.
+ * (Or not implemented the fatal routine properly, but that is your problem.)
+ *
+ * I'm indebted to many people who helped me in one way or another to write
+ * this code. During the design of Twofish and the AES process I had very
+ * extensive discussions of all implementation issues with various people.
+ * Doug Whiting in particular provided a wealth of information. The Twofish
+ * team spent untold hours discussion various cipher features, and their
+ * implementation. Brian Gladman implemented all AES candidates in C,
+ * and we had some fruitful discussions on how to implement Twofish in C.
+ * Jan Nieuwenhuizen tested this code on Linux using GCC.
+ *
+ * Now for the license:
+ * The author hereby grants a perpetual license to everybody to
+ * use this code for any purpose as long as the copyright message is included
+ * in the source code of this or any derived work.
+ *
+ * Yes, this means that you, your company, your club, and anyone else
+ * can use this code anywhere you want. You can change it and distribute it
+ * under the GPL, include it in your commercial product without releasing
+ * the source code, put it on the web, etc.
+ * The only thing you cannot do is remove my copyright message,
+ * or distribute any source code based on this implementation that does not
+ * include my copyright message.
+ *
+ * I appreciate a mention in the documentation or credits,
+ * but I understand if that is difficult to do.
+ * I also appreciate it if you tell me where and why you used my code.
+ *
+ * Please send any questions or comments to niels@ferguson.net
+ *
+ * Have Fun!
+ *
+ * Niels
+ */
+
+/*
+ * DISCLAIMER: As I'm giving away my work for free, I'm of course not going
+ * to accept any liability of any form. This code, or the Twofish cipher,
+ * might very well be flawed; you have been warned.
+ * This software is provided as-is, without any kind of warrenty or
+ * guarantee. And that is really all you can expect when you download
+ * code for free from the Internet.
+ *
+ * I think it is really sad that disclaimers like this seem to be necessary.
+ * If people only had a little bit more common sense, and didn't come
+ * whining like little children every time something happens....
+ */
+
+/*
+ * Version history:
+ * Version 0.0, 2002-08-30
+ * First written.
+ * Version 0.1, 2002-09-03
+ * Added disclaimer. Improved self-tests.
+ * Version 0.2, 2002-09-09
+ * Removed last non-portabilities. Default now works completely within
+ * the C standard. UInt32 can be larger than 32 bits without problems.
+ * Version 0.3, 2002-09-28
+ * Bugfix: use instead of to adhere to ANSI/ISO.
+ * Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library
+ * header already defines BIG_ENDIAN, even though it is not
+ * supposed to.
+ */
+
+
+/*
+ * Minimum set of include files.
+ * You should not need any application-specific include files for this code.
+ * In fact, adding you own header files could break one of the many macros or
+ * functions in this file. Be very careful.
+ * Standard include files will probably be ok.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/* #include * for memset(), memcpy(), and memcmp() */
+#include "twofish.h"
+
+
+/*
+ * PLATFORM FIXES
+ * ==============
+ *
+ * Fix the type definitions in twofish.h first!
+ *
+ * The following definitions have to be fixed for each particular platform
+ * you work on. If you have a multi-platform program, you no doubt have
+ * portable definitions that you can substitute here without changing the
+ * rest of the code.
+ */
+
+
+/*
+ * Function called if something is fatally wrong with the implementation.
+ * This fatal function is called when a coding error is detected in the
+ * Twofish implementation, or when somebody passes an obviously erroneous
+ * parameter to this implementation. There is not much you can do when
+ * the code contains bugs, so we just stop.
+ *
+ * The argument is a string. Ideally the fatal function prints this string
+ * as an error message. Whatever else this function does, it should never
+ * return. A typical implementation would stop the program completely after
+ * printing the error message.
+ *
+ * This default implementation is not very useful,
+ * but does not assume anything about your environment.
+ * It will at least let you know something is wrong....
+ * I didn't want to include any libraries to print and error or so,
+ * as this makes the code much harder to integrate in a project.
+ *
+ * Note that the Twofish_fatal function may not return to the caller.
+ * Unfortunately this is not something the self-test can test for,
+ * so you have to make sure of this yourself.
+ *
+ * If you want to call an external function, be careful about including
+ * your own header files here. This code uses a lot of macros, and your
+ * header file could easily break it. Maybe the best solution is to use
+ * a separate extern statement for your fatal function.
+ */
+/* #define Twofish_fatal(pmsgx) { fprintf(stderr, pmsgx); exit(1); } */
+#define Twofish_fatal(pmsgx, code) { return(code); }
+
+
+/*
+ * The rest of the settings are not important for the functionality
+ * of this Twofish implementation. That is, their default settings
+ * work on all platforms. You can change them to improve the
+ * speed of the implementation on your platform. Erroneous settings
+ * will result in erroneous implementations, but the self-test should
+ * catch those.
+ */
+
+
+/*
+ * Macros to rotate a Twofish_UInt32 value left or right by the
+ * specified number of bits. This should be a 32-bit rotation,
+ * and not rotation of, say, 64-bit values.
+ *
+ * Every encryption or decryption operation uses 32 of these rotations,
+ * so it is a good idea to make these macros efficient.
+ *
+ * This fully portable definition has one piece of tricky stuff.
+ * The UInt32 might be larger than 32 bits, so we have to mask
+ * any higher bits off. The simplest way to do this is to 'and' the
+ * value first with 0xffffffff and then shift it right. An optimising
+ * compiler that has a 32-bit type can optimise this 'and' away.
+ *
+ * Unfortunately there is no portable way of writing the constant
+ * 0xffffffff. You don't know which suffix to use (U, or UL?)
+ * The UINT32_MASK definition uses a bit of trickery. Shift-left
+ * is only defined if the shift amount is strictly less than the size
+ * of the UInt32, so we can't use (1<<32). The answer it to take the value
+ * 2, cast it to a UInt32, shift it left 31 positions, and subtract one.
+ * Another example of how to make something very simple extremely difficult.
+ * I hate C.
+ *
+ * The rotation macros are straightforward.
+ * They are only applied to UInt32 values, which are _unsigned_
+ * so the >> operator must do a logical shift that brings in zeroes.
+ * On most platforms you will only need to optimise the ROL32 macro; the
+ * ROR32 macro is not inefficient on an optimising compiler as all rotation
+ * amounts in this code are known at compile time.
+ *
+ * On many platforms there is a faster solution.
+ * For example, MS compilers have the __rotl and __rotr functions
+ * that generate x86 rotation instructions.
+ */
+#define UINT32_MASK ( (((Twofish_UInt32)2)<<31) - 1 )
+
+#ifndef _MSC_VER
+#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) )
+#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) )
+#else
+#define ROL32(x,n) (_lrotl((x), (n)))
+#define ROR32(x,n) (_lrotr((x), (n)))
+#endif
+
+/*
+ * Select data type for q-table entries.
+ *
+ * Larger entry types cost more memory (1.5 kB), and might be faster
+ * or slower depending on the CPU and compiler details.
+ *
+ * This choice only affects the static data size and the key setup speed.
+ * Functionality, expanded key size, or encryption speed are not affected.
+ * Define to 1 to get large q-table entries.
+ */
+#define LARGE_Q_TABLE 0 /* default = 0 */
+
+
+/*
+ * Method to select a single byte from a UInt32.
+ * WARNING: non-portable code if set; might not work on all platforms.
+ *
+ * Inside the inner loop of Twofish it is necessary to access the 4
+ * individual bytes of a UInt32. This can be done using either shifts
+ * and masks, or memory accesses.
+ *
+ * Set to 0 to use shift and mask operations for the byte selection.
+ * This is more ALU intensive. It is also fully portable.
+ *
+ * Set to 1 to use memory accesses. The UInt32 is stored in memory and
+ * the individual bytes are read from memory one at a time.
+ * This solution is more memory-intensive, and not fully portable.
+ * It might be faster on your platform, or not. If you use this option,
+ * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately.
+ *
+ * This macro does not affect the conversion of the inputs and outputs
+ * of the cipher. See the CONVERT_USING_CASTS macro for that.
+ */
+#define SELECT_BYTE_FROM_UINT32_IN_MEMORY 0 /* default = 0 */
+
+
+/*
+ * Method used to read the input and write the output.
+ * WARNING: non-portable code if set; might not work on all platforms.
+ *
+ * Twofish operates on 32-bit words. The input to the cipher is
+ * a byte array, as is the output. The portable method of doing the
+ * conversion is a bunch of rotate and mask operations, but on many
+ * platforms it can be done faster using a cast.
+ * This only works if your CPU allows UInt32 accesses to arbitrary Byte
+ * addresses.
+ *
+ * Set to 0 to use the shift and mask operations. This is fully
+ * portable. .
+ *
+ * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a
+ * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN
+ * macro) the byte order in the UInt32 is swapped. The reverse is done
+ * to write the output of the encryption/decryption. Make sure you set
+ * the CPU_IS_BIG_ENDIAN flag appropriately.
+ * This option does not work unless a UInt32 is exactly 32 bits.
+ *
+ * This macro only changes the reading/writing of the plaintext/ciphertext.
+ * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which
+ * a UInt32 is split into 4 bytes for the S-box selection.
+ */
+#define CONVERT_USING_CASTS 0 /* default = 0 */
+
+
+/*
+ * Endianness switch.
+ * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or
+ * CONVERT_USING_CASTS is set.
+ *
+ * Set to 1 on a big-endian machine, and to 0 on a little-endian machine.
+ * Twofish uses the little-endian convention (least significant byte first)
+ * and big-endian machines (using most significant byte first)
+ * have to do a few conversions.
+ *
+ * CAUTION: This code has never been tested on a big-endian machine,
+ * because I don't have access to one. Feedback appreciated.
+ */
+#define CPU_IS_BIG_ENDIAN 0
+
+
+/*
+ * Macro to reverse the order of the bytes in a UInt32.
+ * Used to convert to little-endian on big-endian machines.
+ * This macro is always tested, but only used in the encryption and
+ * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN
+ * are both set. In other words: this macro is only speed-critical if
+ * both these flags have been set.
+ *
+ * This default definition of SWAP works, but on many platforms there is a
+ * more efficient implementation.
+ */
+#define BSWAP(x) ((ROL32((x),8)&0x00ff00ff) | (ROR32((x),8) & 0xff00ff00))
+
+
+/*
+ * END OF PLATFORM FIXES
+ * =====================
+ *
+ * You should not have to touch the rest of this file.
+ */
+
+
+/*
+ * Convert the external type names to some that are easier to use inside
+ * this file. I didn't want to use the names Byte and UInt32 in the
+ * header file, because many programs already define them and using two
+ * conventions at once can be very difficult.
+ * Don't change these definitions! Change the originals
+ * in twofish.h instead.
+ */
+/* A Byte must be an unsigned integer, 8 bits long. */
+/* typedef Twofish_Byte Byte; */
+/* A UInt32 must be an unsigned integer at least 32 bits long. */
+/* typedef Twofish_UInt32 UInt32; */
+
+
+/*
+ * Define a macro ENDIAN_CONVERT.
+ *
+ * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian
+ * machines, and is the identity function on little-endian machines.
+ * The code then uses this macro without considering the endianness.
+ */
+
+#if CPU_IS_BIG_ENDIAN
+#define ENDIAN_CONVERT(x) BSWAP(x)
+#else
+#define ENDIAN_CONVERT(x) (x)
+#endif
+
+
+/*
+ * Compute byte offset within a UInt32 stored in memory.
+ *
+ * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set.
+ *
+ * The input is the byte number 0..3, 0 for least significant.
+ * Note the use of sizeof() to support UInt32 types that are larger
+ * than 4 bytes.
+ */
+#if CPU_IS_BIG_ENDIAN
+#define BYTE_OFFSET( n ) (sizeof(Twofish_UInt32) - 1 - (n) )
+#else
+#define BYTE_OFFSET( n ) (n)
+#endif
+
+
+/*
+ * Macro to get Byte no. b from UInt32 value X.
+ * We use two different definition, depending on the settings.
+ */
+#if SELECT_BYTE_FROM_UINT32_IN_MEMORY
+ /* Pick the byte from the memory in which X is stored. */
+#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)])
+#else
+ /* Portable solution: Pick the byte directly from the X value. */
+#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff)
+#endif
+
+
+/* Some shorthands because we use byte selection in large formulae. */
+#define b0(X) SELECT_BYTE((X),0)
+#define b1(X) SELECT_BYTE((X),1)
+#define b2(X) SELECT_BYTE((X),2)
+#define b3(X) SELECT_BYTE((X),3)
+
+
+/*
+ * We need macros to load and store UInt32 from/to byte arrays
+ * using the least-significant-byte-first convention.
+ *
+ * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to
+ * by p.
+ * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form.
+ */
+#if CONVERT_USING_CASTS
+
+ /* Get UInt32 from four bytes pointed to by p. */
+#define GET32( p ) ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) )
+ /* Put UInt32 into four bytes pointed to by p */
+#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v)
+
+#else
+
+ /* Get UInt32 from four bytes pointed to by p. */
+#define GET32( p ) \
+ ( \
+ (Twofish_UInt32)((p)[0]) \
+ | (Twofish_UInt32)((p)[1])<< 8 \
+ | (Twofish_UInt32)((p)[2])<<16 \
+ | (Twofish_UInt32)((p)[3])<<24 \
+ )
+ /* Put UInt32 into four bytes pointed to by p */
+#define PUT32( v, p ) \
+ (p)[0] = (Twofish_Byte)(((v) ) & 0xff); \
+ (p)[1] = (Twofish_Byte)(((v) >> 8) & 0xff); \
+ (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \
+ (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)
+
+#endif
+
+
+/*
+ * Test the platform-specific macros.
+ * This function tests the macros defined so far to make sure the
+ * definitions are appropriate for this platform.
+ * If you make any mistake in the platform configuration, this should detect
+ * that and inform you what went wrong.
+ * Somewhere, someday, this is going to save somebody a lot of time,
+ * because misbehaving macros are hard to debug.
+ */
+static int test_platform()
+ {
+ /* Buffer with test values. */
+ Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0};
+ Twofish_UInt32 C;
+ Twofish_UInt32 x,y;
+ int i;
+
+ /*
+ * Some sanity checks on the types that can't be done in compile time.
+ * A smart compiler will just optimise these tests away.
+ * The pre-processor doesn't understand different types, so we cannot
+ * do these checks in compile-time.
+ *
+ * I hate C.
+ *
+ * The first check in each case is to make sure the size is correct.
+ * The second check is to ensure that it is an unsigned type.
+ */
+ if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 ))
+ {
+ Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable", ERR_UINT32 );
+ }
+ if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) )
+ {
+ Twofish_fatal( "Twofish code: Twofish_Byte type not suitable", ERR_BYTE );
+ }
+
+ /*
+ * Sanity-check the endianness conversions.
+ * This is just an aid to find problems. If you do the endianness
+ * conversion macros wrong you will fail the full cipher test,
+ * but that does not help you find the error.
+ * Always make it easy to find the bugs!
+ *
+ * Detail: There is no fully portable way of writing UInt32 constants,
+ * as you don't know whether to use the U or UL suffix. Using only U you
+ * might only be allowed 16-bit constants. Using UL you might get 64-bit
+ * constants which cannot be stored in a UInt32 without warnings, and
+ * which generally behave subtly different from a true UInt32.
+ * As long as we're just comparing with the constant,
+ * we can always use the UL suffix and at worst lose some efficiency.
+ * I use a separate '32-bit constant' macro in most of my other code.
+ *
+ * I hate C.
+ *
+ * Start with testing GET32. We test it on all positions modulo 4
+ * to make sure we can handly any position of inputs. (Some CPUs
+ * do not allow non-aligned accesses which we would do if you used
+ * the CONVERT_USING_CASTS option.
+ */
+ if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL)
+ || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) )
+ {
+ Twofish_fatal( "Twofish code: GET32 not implemented properly", ERR_GET32 );
+ }
+
+ /*
+ * We can now use GET32 to test PUT32.
+ * We don't test the shifted versions. If GET32 can do that then
+ * so should PUT32.
+ */
+ C = GET32( buf );
+ PUT32( 3*C, buf );
+ if( GET32( buf ) != 0x69029c36UL )
+ {
+ Twofish_fatal( "Twofish code: PUT32 not implemented properly", ERR_PUT32 );
+ }
+
+
+ /* Test ROL and ROR */
+ for( i=1; i<32; i++ )
+ {
+ /* Just a simple test. */
+ x = ROR32( C, i );
+ y = ROL32( C, i );
+ x ^= (C>>i) ^ (C<<(32-i));
+ /*y ^= (C<>(32-i)); */
+ y ^= (C<<i) ^ (C>>(32-i));
+ x |= y;
+ /*
+ * Now all we check is that x is zero in the least significant
+ * 32 bits. Using the UL suffix is safe here, as it doesn't matter
+ * if we get a larger type.
+ */
+ if( (x & 0xffffffffUL) != 0 )
+ {
+ Twofish_fatal( "Twofish ROL or ROR not properly defined.", ERR_ROLR );
+ }
+ }
+
+ /* Test the BSWAP macro */
+ if( BSWAP(C) != 0x12345678UL )
+ {
+ /*
+ * The BSWAP macro should always work, even if you are not using it.
+ * A smart optimising compiler will just remove this entire test.
+ */
+ Twofish_fatal( "BSWAP not properly defined.", ERR_BSWAP );
+ }
+
+ /* And we can test the b macros which use SELECT_BYTE. */
+ if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) )
+ {
+ /*
+ * There are many reasons why this could fail.
+ * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value.
+ */
+ Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly", ERR_SELECTB );
+ }
+ return SUCCESS;
+ }
+
+
+/*
+ * Finally, we can start on the Twofish-related code.
+ * You really need the Twofish specifications to understand this code. The
+ * best source is the Twofish book:
+ * "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson.
+ * you can also use the AES submission document of Twofish, which is
+ * available from my list of publications on my personal web site at
+ * http://niels.ferguson.net/.
+ *
+ * The first thing we do is write the testing routines. This is what the
+ * implementation has to satisfy in the end. We only test the external
+ * behaviour of the implementation of course.
+ */
+
+
+/*
+ * Perform a single self test on a (plaintext,ciphertext,key) triple.
+ * Arguments:
+ * key array of key bytes
+ * key_len length of key in bytes
+ * p plaintext
+ * c ciphertext
+ */
+static int test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] )
+ {
+ Twofish_Byte tmp[16]; /* scratch pad. */
+ Twofish_key xkey; /* The expanded key */
+ int i;
+
+
+ /* Prepare the key */
+ if ((i = Twofish_prepare_key( key, key_len, &xkey)) < 0)
+ return i;
+
+ /*
+ * We run the test twice to ensure that the xkey structure
+ * is not damaged by the first encryption.
+ * Those are hideous bugs to find if you get them in an application.
+ */
+ for( i=0; i<2; i++ )
+ {
+ /* Encrypt and test */
+ Twofish_encrypt( &xkey, p, tmp );
+ if( memcmp( c, tmp, 16 ) != 0 )
+ {
+ Twofish_fatal( "Twofish encryption failure", ERR_TEST_ENC );
+ }
+
+ /* Decrypt and test */
+ Twofish_decrypt( &xkey, c, tmp );
+ if( memcmp( p, tmp, 16 ) != 0 )
+ {
+ Twofish_fatal( "Twofish decryption failure", ERR_TEST_DEC );
+ }
+ }
+
+ /* The test keys are not secret, so we don't need to wipe xkey. */
+ return SUCCESS;
+ }
+
+
+/*
+ * Check implementation using three (key,plaintext,ciphertext)
+ * test vectors, one for each major key length.
+ *
+ * This is an absolutely minimal self-test.
+ * This routine does not test odd-sized keys.
+ */
+static int test_vectors()
+ {
+ /*
+ * We run three tests, one for each major key length.
+ * These test vectors come from the Twofish specification.
+ * One encryption and one decryption using randomish data and key
+ * will detect almost any error, especially since we generate the
+ * tables ourselves, so we don't have the problem of a single
+ * damaged table entry in the source.
+ */
+
+ /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */
+ static Twofish_Byte k128[] = {
+ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+ 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A,
+ };
+ static Twofish_Byte p128[] = {
+ 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
+ 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
+ };
+ static Twofish_Byte c128[] = {
+ 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
+ 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
+ };
+
+ /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */
+ static Twofish_Byte k192[] = {
+ 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
+ 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
+ 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44
+ };
+ static Twofish_Byte p192[] = {
+ 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
+ 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2
+ };
+ static Twofish_Byte c192[] = {
+ 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
+ 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65
+ };
+
+ /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */
+ static Twofish_Byte k256[] = {
+ 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
+ 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
+ 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
+ 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
+ };
+ static Twofish_Byte p256[] = {
+ 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
+ 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
+ };
+ static Twofish_Byte c256[] = {
+ 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
+ 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
+ };
+
+ int ret;
+
+ /* Run the actual tests. */
+ if ((ret = test_vector( k128, 16, p128, c128 )) < 0)
+ return ret;
+ if ((ret = test_vector( k192, 24, p192, c192 )) < 0)
+ return ret;
+ if ((ret = test_vector( k256, 32, p256, c256 )) < 0)
+ return ret;
+ return SUCCESS;
+ }
+
+
+/*
+ * Perform extensive test for a single key size.
+ *
+ * Test a single key size against the test vectors from section
+ * B.2 in the Twofish book. This is a sequence of 49 encryptions
+ * and decryptions. Each plaintext is equal to the ciphertext of
+ * the previous encryption. The key is made up from the ciphertext
+ * two and three encryptions ago. Both plaintext and key start
+ * at the zero value.
+ * We should have designed a cleaner recurrence relation for
+ * these tests, but it is too late for that now. At least we learned
+ * how to do it better next time.
+ * For details see appendix B of the book.
+ *
+ * Arguments:
+ * key_len Number of bytes of key
+ * final_value Final plaintext value after 49 iterations
+ */
+static int test_sequence( int key_len, Twofish_Byte final_value[] )
+ {
+ Twofish_Byte buf[ (50+3)*16 ]; /* Buffer to hold our computation values. */
+ Twofish_Byte tmp[16]; /* Temp for testing the decryption. */
+ Twofish_key xkey; /* The expanded key */
+ int i, ret;
+ Twofish_Byte * p;
+
+ /* Wipe the buffer */
+ memset( buf, 0, sizeof( buf ) );
+
+ /*
+ * Because the recurrence relation is done in an inconvenient manner
+ * we end up looping backwards over the buffer.
+ */
+
+ /* Pointer in buffer points to current plaintext. */
+ p = &buf[50*16];
+ for( i=1; i<50; i++ )
+ {
+ /*
+ * Prepare a key.
+ * This automatically checks that key_len is valid.
+ */
+ if ((ret = Twofish_prepare_key( p+16, key_len, &xkey)) < 0)
+ return ret;
+
+ /* Compute the next 16 bytes in the buffer */
+ Twofish_encrypt( &xkey, p, p-16 );
+
+ /* Check that the decryption is correct. */
+ Twofish_decrypt( &xkey, p-16, tmp );
+ if( memcmp( tmp, p, 16 ) != 0 )
+ {
+ Twofish_fatal( "Twofish decryption failure in sequence", ERR_SEQ_DEC );
+ }
+ /* Move on to next 16 bytes in the buffer. */
+ p -= 16;
+ }
+
+ /* And check the final value. */
+ if( memcmp( p, final_value, 16 ) != 0 )
+ {
+ Twofish_fatal( "Twofish encryption failure in sequence", ERR_SEQ_ENC );
+ }
+
+ /* None of the data was secret, so there is no need to wipe anything. */
+ return SUCCESS;
+ }
+
+
+/*
+ * Run all three sequence tests from the Twofish test vectors.
+ *
+ * This checks the most extensive test vectors currently available
+ * for Twofish. The data is from the Twofish book, appendix B.2.
+ */
+static int test_sequences()
+ {
+ static Twofish_Byte r128[] = {
+ 0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57,
+ 0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0
+ };
+ static Twofish_Byte r192[] = {
+ 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4,
+ 0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41
+ };
+ static Twofish_Byte r256[] = {
+ 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75,
+ 0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05
+ };
+
+ /* Run the three sequence test vectors */
+ int ret;
+ if ((ret = test_sequence( 16, r128)) < 0)
+ return ret;
+ if ((ret = test_sequence( 24, r192)) < 0)
+ return ret;
+ if ((ret = test_sequence( 32, r256)) < 0)
+ return ret;
+ return SUCCESS;
+ }
+
+
+/*
+ * Test the odd-sized keys.
+ *
+ * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits.
+ * The equivalent key is found by padding at the end with zero bytes
+ * until a regular key size is reached.
+ *
+ * We just test that the key expansion routine behaves properly.
+ * If the expanded keys are identical, then the encryptions and decryptions
+ * will behave the same.
+ */
+static int test_odd_sized_keys()
+ {
+ Twofish_Byte buf[32];
+ Twofish_key xkey;
+ Twofish_key xkey_two;
+ int i, ret;
+
+ /*
+ * We first create an all-zero key to use as PRNG key.
+ * Normally we would not have to fill the buffer with zeroes, as we could
+ * just pass a zero key length to the Twofish_prepare_key function.
+ * However, this relies on using odd-sized keys, and those are just the
+ * ones we are testing here. We can't use an untested function to test
+ * itself.
+ */
+ memset( buf, 0, sizeof( buf ) );
+ if ((ret = Twofish_prepare_key( buf, 16, &xkey)) < 0)
+ return ret;
+
+ /* Fill buffer with pseudo-random data derived from two encryptions */
+ Twofish_encrypt( &xkey, buf, buf );
+ Twofish_encrypt( &xkey, buf, buf+16 );
+
+ /* Create all possible shorter keys that are prefixes of the buffer. */
+ for( i=31; i>=0; i-- )
+ {
+ /* Set a byte to zero. This is the new padding byte */
+ buf[i] = 0;
+
+ /* Expand the key with only i bytes of length */
+ if ((ret = Twofish_prepare_key( buf, i, &xkey)) < 0)
+ return ret;
+
+ /* Expand the corresponding padded key of regular length */
+ if ((ret = Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two )) < 0)
+ return ret;
+
+ /* Compare the two */
+ if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 )
+ {
+ Twofish_fatal( "Odd sized keys do not expand properly", ERR_ODD_KEY );
+ }
+ }
+
+ /* None of the key values are secret, so we don't need to wipe them. */
+ return SUCCESS;
+ }
+
+
+/*
+ * Test the Twofish implementation.
+ *
+ * This routine runs all the self tests, in order of importance.
+ * It is called by the Twofish_initialise routine.
+ *
+ * In almost all applications the cost of running the self tests during
+ * initialisation is insignificant, especially
+ * compared to the time it takes to load the application from disk.
+ * If you are very pressed for initialisation performance,
+ * you could remove some of the tests. Make sure you did run them
+ * once in the software and hardware configuration you are using.
+ */
+static int self_test()
+ {
+ int ret;
+ /* The three test vectors form an absolute minimal test set. */
+ if ((ret = test_vectors()) < 0)
+ return ret;
+
+ /*
+ * If at all possible you should run these tests too. They take
+ * more time, but provide a more thorough coverage.
+ */
+ if ((ret = test_sequences()) < 0)
+ return ret;
+
+ /* Test the odd-sized keys. */
+ if ((ret = test_odd_sized_keys()) < 0)
+ return ret;
+ return SUCCESS;
+ }
+
+
+/*
+ * And now, the actual Twofish implementation.
+ *
+ * This implementation generates all the tables during initialisation.
+ * I don't like large tables in the code, especially since they are easily
+ * damaged in the source without anyone noticing it. You need code to
+ * generate them anyway, and this way all the code is close together.
+ * Generating them in the application leads to a smaller executable
+ * (the code is smaller than the tables it generates) and a
+ * larger static memory footprint.
+ *
+ * Twofish can be implemented in many ways. I have chosen to
+ * use large tables with a relatively long key setup time.
+ * If you encrypt more than a few blocks of data it pays to pre-compute
+ * as much as possible. This implementation is relatively inefficient for
+ * applications that need to re-key every block or so.
+ */
+
+/*
+ * We start with the t-tables, directly from the Twofish definition.
+ * These are nibble-tables, but merging them and putting them two nibbles
+ * in one byte is more work than it is worth.
+ */
+static Twofish_Byte t_table[2][4][16] = {
+ {
+ {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4},
+ {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD},
+ {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1},
+ {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA}
+ },
+ {
+ {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5},
+ {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8},
+ {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF},
+ {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA}
+ }
+};
+
+
+/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */
+#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) )
+
+/*
+ * The q-boxes are only used during the key schedule computations.
+ * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit
+ * lookup tables as it is faster to load a 32-bit value than to load an
+ * 8-bit value and zero the rest of the register.
+ * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in
+ * the q-tables. Here we just define the Qtype which is used to store
+ * the entries of the q-tables.
+ */
+#if LARGE_Q_TABLE
+typedef Twofish_UInt32 Qtype;
+#else
+typedef Twofish_Byte Qtype;
+#endif
+
+/*
+ * The actual q-box tables.
+ * There are two q-boxes, each having 256 entries.
+ */
+static Qtype q_table[2][256];
+
+
+/*
+ * Now the function that converts a single t-table into a q-table.
+ *
+ * Arguments:
+ * t[4][16] : four 4->4bit lookup tables that define the q-box
+ * q[256] : output parameter: the resulting q-box as a lookup table.
+ */
+static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] )
+ {
+ int ae,be,ao,bo; /* Some temporaries. */
+ int i;
+ /* Loop over all input values and compute the q-box result. */
+ for( i=0; i<256; i++ ) {
+ /*
+ * This is straight from the Twofish specifications.
+ *
+ * The ae variable is used for the a_i values from the specs
+ * with even i, and ao for the odd i's. Similarly for the b's.
+ */
+ ae = i>>4; be = i&0xf;
+ ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
+ ae = t[0][ao]; be = t[1][bo];
+ ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
+ ae = t[2][ao]; be = t[3][bo];
+
+ /* Store the result in the q-box table, the cast avoids a warning. */
+ q[i] = (Qtype) ((be<<4) | ae);
+ }
+ }
+
+
+/*
+ * Initialise both q-box tables.
+ */
+static void initialise_q_boxes() {
+ /* Initialise each of the q-boxes using the t-tables */
+ make_q_table( t_table[0], q_table[0] );
+ make_q_table( t_table[1], q_table[1] );
+ }
+
+
+/*
+ * Next up is the MDS matrix multiplication.
+ * The MDS matrix multiplication operates in the field
+ * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1.
+ * If you don't understand this, read a book on finite fields. You cannot
+ * follow the finite-field computations without some background.
+ *
+ * In this field, multiplication by x is easy: shift left one bit
+ * and if bit 8 is set then xor the result with 0x169.
+ *
+ * The MDS coefficients use a multiplication by 1/x,
+ * or rather a division by x. This is easy too: first make the
+ * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary,
+ * and then shift right one position.
+ * Even easier: shift right and xor with 0xb4 if the lsbit was set.
+ *
+ * The MDS coefficients are 1, EF, and 5B, and we use the fact that
+ * EF = 1 + 1/x + 1/x^2
+ * 5B = 1 + 1/x^2
+ * in this field. This makes multiplication by EF and 5B relatively easy.
+ *
+ * This property is no accident, the MDS matrix was designed to allow
+ * this implementation technique to be used.
+ *
+ * We have four MDS tables, each mapping 8 bits to 32 bits.
+ * Each table performs one column of the matrix multiplication.
+ * As the MDS is always preceded by q-boxes, each of these tables
+ * also implements the q-box just previous to that column.
+ */
+
+/* The actual MDS tables. */
+static Twofish_UInt32 MDS_table[4][256];
+
+/* A small table to get easy conditional access to the 0xb4 constant. */
+static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4};
+
+/* Function to initialise the MDS tables. */
+static void initialise_mds_tables()
+ {
+ int i;
+ Twofish_UInt32 q,qef,q5b; /* Temporary variables. */
+
+ /* Loop over all 8-bit input values */
+ for( i=0; i<256; i++ )
+ {
+ /*
+ * To save some work during the key expansion we include the last
+ * of the q-box layers from the h() function in these MDS tables.
+ */
+
+ /* We first do the inputs that are mapped through the q0 table. */
+ q = q_table[0][i];
+ /*
+ * Here we divide by x, note the table to get 0xb4 only if the
+ * lsbit is set.
+ * This sets qef = (1/x)*q in the finite field
+ */
+ qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
+ /*
+ * Divide by x again, and add q to get (1+1/x^2)*q.
+ * Note that (1+1/x^2) = 5B in the field, and addition in the field
+ * is exclusive or on the bits.
+ */
+ q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
+ /*
+ * Add q5b to qef to set qef = (1+1/x+1/x^2)*q.
+ * Again, (1+1/x+1/x^2) = EF in the field.
+ */
+ qef ^= q5b;
+
+ /*
+ * Now that we have q5b = 5B * q and qef = EF * q
+ * we can fill two of the entries in the MDS matrix table.
+ * See the Twofish specifications for the order of the constants.
+ */
+ MDS_table[1][i] = (q <<24) | (q5b<<16) | (qef<<8) | qef;
+ MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q <<8) | q5b;
+
+ /* Now we do it all again for the two columns that have a q1 box. */
+ q = q_table[1][i];
+ qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
+ q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
+ qef ^= q5b;
+
+ /* The other two columns use the coefficient in a different order. */
+ MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q ;
+ MDS_table[2][i] = (qef<<24) | (q <<16) | (qef<<8) | q5b;
+ }
+ }
+
+
+/*
+ * The h() function is the heart of the Twofish cipher.
+ * It is a complicated sequence of q-box lookups, key material xors,
+ * and finally the MDS matrix.
+ * We use lots of macros to make this reasonably fast.
+ */
+
+/* First a shorthand for the two q-tables */
+#define q0 q_table[0]
+#define q1 q_table[1]
+
+/*
+ * Each macro computes one column of the h for either 2, 3, or 4 stages.
+ * As there are 4 columns, we have 12 macros in all.
+ *
+ * The key bytes are stored in the Byte array L at offset
+ * 0,1,2,3, 8,9,10,11, [16,17,18,19, [24,25,26,27]] as this is the
+ * order we get the bytes from the user. If you look at the Twofish
+ * specs, you'll see that h() is applied to the even key words or the
+ * odd key words. The bytes of the even words appear in this spacing,
+ * and those of the odd key words too.
+ *
+ * These macros are the only place where the q-boxes and the MDS table
+ * are used.
+ */
+#define H02( y, L ) MDS_table[0][q0[q0[y]^L[ 8]]^L[0]]
+#define H12( y, L ) MDS_table[1][q0[q1[y]^L[ 9]]^L[1]]
+#define H22( y, L ) MDS_table[2][q1[q0[y]^L[10]]^L[2]]
+#define H32( y, L ) MDS_table[3][q1[q1[y]^L[11]]^L[3]]
+#define H03( y, L ) H02( q1[y]^L[16], L )
+#define H13( y, L ) H12( q1[y]^L[17], L )
+#define H23( y, L ) H22( q0[y]^L[18], L )
+#define H33( y, L ) H32( q0[y]^L[19], L )
+#define H04( y, L ) H03( q1[y]^L[24], L )
+#define H14( y, L ) H13( q0[y]^L[25], L )
+#define H24( y, L ) H23( q0[y]^L[26], L )
+#define H34( y, L ) H33( q1[y]^L[27], L )
+
+/*
+ * Now we can define the h() function given an array of key bytes.
+ * This function is only used in the key schedule, and not to pre-compute
+ * the keyed S-boxes.
+ *
+ * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24)
+ * so we only provide k as an argument.
+ *
+ * Arguments:
+ * k input to the h() function.
+ * L pointer to array of key bytes at
+ * offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]]
+ * kCycles # key cycles, 2, 3, or 4.
+ */
+static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles )
+ {
+ switch( kCycles ) {
+ /* We code all 3 cases separately for speed reasons. */
+ case 2:
+ return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L);
+ case 3:
+ return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L);
+ case 4:
+ return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L);
+ default:
+ /* This is always a coding error, which is fatal. */
+ Twofish_fatal( "Twofish h(): Illegal argument", ERR_ILL_ARG );
+ return ERR_ILL_ARG;
+ }
+ }
+
+
+/*
+ * Pre-compute the keyed S-boxes.
+ * Fill the pre-computed S-box array in the expanded key structure.
+ * Each pre-computed S-box maps 8 bits to 32 bits.
+ *
+ * The S argument contains half the number of bytes of the full key, but is
+ * derived from the full key. (See Twofish specifications for details.)
+ * S has the weird byte input order used by the Hxx macros.
+ *
+ * This function takes most of the time of a key expansion.
+ *
+ * Arguments:
+ * S pointer to array of 8*kCycles Bytes containing the S vector.
+ * kCycles number of key words, must be in the set {2,3,4}
+ * xkey pointer to Twofish_key structure that will contain the S-boxes.
+ */
+static int fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey )
+ {
+ int i;
+ switch( kCycles ) {
+ /* We code all 3 cases separately for speed reasons. */
+ case 2:
+ for( i=0; i<256; i++ )
+ {
+ xkey->s[0][i]= H02( i, S );
+ xkey->s[1][i]= H12( i, S );
+ xkey->s[2][i]= H22( i, S );
+ xkey->s[3][i]= H32( i, S );
+ }
+ break;
+ case 3:
+ for( i=0; i<256; i++ )
+ {
+ xkey->s[0][i]= H03( i, S );
+ xkey->s[1][i]= H13( i, S );
+ xkey->s[2][i]= H23( i, S );
+ xkey->s[3][i]= H33( i, S );
+ }
+ break;
+ case 4:
+ for( i=0; i<256; i++ )
+ {
+ xkey->s[0][i]= H04( i, S );
+ xkey->s[1][i]= H14( i, S );
+ xkey->s[2][i]= H24( i, S );
+ xkey->s[3][i]= H34( i, S );
+ }
+ break;
+ default:
+ /* This is always a coding error, which is fatal. */
+ Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument", ERR_ILL_ARG );
+ }
+ return SUCCESS;
+ }
+
+
+/* A flag to keep track of whether we have been initialised or not. */
+static int Twofish_initialised = 0;
+
+/*
+ * Initialise the Twofish implementation.
+ * This function must be called before any other function in the
+ * Twofish implementation is called.
+ * This routine also does some sanity checks, to make sure that
+ * all the macros behave, and it tests the whole cipher.
+ */
+int Twofish_initialise()
+ {
+ int ret;
+ /* First test the various platform-specific definitions. */
+ if ((ret = test_platform()) < 0)
+ return ret;
+
+ /* We can now generate our tables, in the right order of course. */
+ initialise_q_boxes();
+ initialise_mds_tables();
+
+ /* We're finished with the initialisation itself. */
+ Twofish_initialised = 1;
+
+ /*
+ * And run some tests on the whole cipher.
+ * Yes, you need to do this every time you start your program.
+ * It is called assurance; you have to be certain that your program
+ * still works properly.
+ */
+ return self_test();
+ }
+
+
+/*
+ * The Twofish key schedule uses an Reed-Solomon code matrix multiply.
+ * Just like the MDS matrix, the RS-matrix is designed to be easy
+ * to implement. Details are below in the code.
+ *
+ * These constants make it easy to compute in the finite field used
+ * for the RS code.
+ *
+ * We use Bytes for the RS computation, but these are automatically
+ * widened to unsigned integers in the expressions. Having unsigned
+ * ints in these tables therefore provides the fastest access.
+ */
+static unsigned int rs_poly_const[] = {0, 0x14d};
+static unsigned int rs_poly_div_const[] = {0, 0xa6 };
+
+
+/*
+ * Prepare a key for use in encryption and decryption.
+ * Like most block ciphers, Twofish allows the key schedule
+ * to be pre-computed given only the key.
+ * Twofish has a fairly 'heavy' key schedule that takes a lot of time
+ * to compute. The main work is pre-computing the S-boxes used in the
+ * encryption and decryption. We feel that this makes the cipher much
+ * harder to attack. The attacker doesn't even know what the S-boxes
+ * contain without including the entire key schedule in the analysis.
+ *
+ * Unlike most Twofish implementations, this one allows any key size from
+ * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the
+ * specifications); the key is simply padded with zeroes to the next real
+ * key size of 16, 24, or 32 bytes.
+ * Each odd-sized key is thus equivalent to a single normal-sized key.
+ *
+ * Arguments:
+ * key array of key bytes
+ * key_len number of bytes in the key, must be in the range 0,...,32.
+ * xkey Pointer to an Twofish_key structure that will be filled
+ * with the internal form of the cipher key.
+ */
+int Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey )
+ {
+ /* We use a single array to store all key material in,
+ * to simplify the wiping of the key material at the end.
+ * The first 32 bytes contain the actual (padded) cipher key.
+ * The next 32 bytes contain the S-vector in its weird format,
+ * and we have 4 bytes of overrun necessary for the RS-reduction.
+ */
+ Twofish_Byte K[32+32+4];
+
+ int kCycles; /* # key cycles, 2,3, or 4. */
+
+ int i;
+ Twofish_UInt32 A, B; /* Used to compute the round keys. */
+
+ Twofish_Byte * kptr; /* Three pointers for the RS computation. */
+ Twofish_Byte * sptr;
+ Twofish_Byte * t;
+
+ Twofish_Byte b,bx,bxx; /* Some more temporaries for the RS computation. */
+
+ /* Check that the Twofish implementation was initialised. */
+ if( Twofish_initialised == 0 )
+ {
+ /*
+ * You didn't call Twofish_initialise before calling this routine.
+ * This is a programming error, and therefore we call the fatal
+ * routine.
+ *
+ * I could of course call the initialisation routine here,
+ * but there are a few reasons why I don't. First of all, the
+ * self-tests have to be done at startup. It is no good to inform
+ * the user that the cipher implementation fails when he wants to
+ * write his data to disk in encrypted form. You have to warn him
+ * before he spends time typing his data. Second, the initialisation
+ * and self test are much slower than a single key expansion.
+ * Calling the initialisation here makes the performance of the
+ * cipher unpredictable. This can lead to really weird problems
+ * if you use the cipher for a real-time task. Suddenly it fails
+ * once in a while the first time you try to use it. Things like
+ * that are almost impossible to debug.
+ */
+ /* Twofish_fatal( "Twofish implementation was not initialised.", ERR_INIT ); */
+
+ /*
+ * There is always a danger that the Twofish_fatal routine returns,
+ * in spite of the specifications that it should not.
+ * (A good programming rule: don't trust the rest of the code.)
+ * This would be disasterous. If the q-tables and MDS-tables have
+ * not been initialised, they are probably still filled with zeroes.
+ * Suppose the MDS-tables are all zero. The key expansion would then
+ * generate all-zero round keys, and all-zero s-boxes. The danger
+ * is that nobody would notice as the encry
+ * mangles the input, and the decryption still 'decrypts' it,
+ * but now in a completely key-independent manner.
+ * To stop such security disasters, we use blunt force.
+ * If your program hangs here: fix the fatal routine!
+ */
+ for(;;); /* Infinite loop, which beats being insecure. */
+ }
+
+ /* Check for valid key length. */
+ if( key_len < 0 || key_len > 32 )
+ {
+ /*
+ * This can only happen if a programmer didn't read the limitations
+ * on the key size.
+ */
+ Twofish_fatal( "Twofish_prepare_key: illegal key length", ERR_KEY_LEN );
+ /*
+ * A return statement just in case the fatal macro returns.
+ * The rest of the code assumes that key_len is in range, and would
+ * buffer-overflow if it wasn't.
+ *
+ * Why do we still use a programming language that has problems like
+ * buffer overflows, when these problems were solved in 1960 with
+ * the development of Algol? Have we not leared anything?
+ */
+ return ERR_KEY_LEN;
+ }
+
+ /* Pad the key with zeroes to the next suitable key length. */
+ memcpy( K, key, key_len );
+ memset( K+key_len, 0, sizeof(K)-key_len );
+
+ /*
+ * Compute kCycles: the number of key cycles used in the cipher.
+ * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys.
+ */
+ kCycles = (key_len + 7) >> 3;
+ /* Handle the special case of very short keys: minimum 2 cycles. */
+ if( kCycles < 2 )
+ {
+ kCycles = 2;
+ }
+
+ /*
+ * From now on we just pretend to have 8*kCycles bytes of
+ * key material in K. This handles all the key size cases.
+ */
+
+ /*
+ * We first compute the 40 expanded key words,
+ * formulas straight from the Twofish specifications.
+ */
+ for( i=0; i<40; i+=2 )
+ {
+ /*
+ * Due to the byte spacing expected by the h() function
+ * we can pick the bytes directly from the key K.
+ * As we use bytes, we never have the little/big endian
+ * problem.
+ *
+ * Note that we apply the rotation function only to simple
+ * variables, as the rotation macro might evaluate its argument
+ * more than once.
+ */
+ A = h( i , K , kCycles );
+ B = h( i+1, K+4, kCycles );
+ B = ROL32( B, 8 );
+
+ /* Compute and store the round keys. */
+ A += B;
+ B += A;
+ xkey->K[i] = A;
+ xkey->K[i+1] = ROL32( B, 9 );
+ }
+
+ /* Wipe variables that contained key material. */
+ A=B=0;
+
+ /*
+ * And now the dreaded RS multiplication that few seem to understand.
+ * The RS matrix is not random, and is specially designed to compute the
+ * RS matrix multiplication in a simple way.
+ *
+ * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a
+ * different field than used for the MDS matrix.
+ * (At least, it is a different representation because all GF(2^8)
+ * representations are equivalent in some form.)
+ *
+ * We take 8 consecutive bytes of the key and interpret them as
+ * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where
+ * the k_i bytes are the key bytes and are elements of the finite field.
+ * We multiply this polynomial by y^4 and reduce it modulo
+ * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1.
+ * using straightforward polynomial modulo reduction.
+ * The coefficients of the result are the result of the RS
+ * matrix multiplication. When we wrote the Twofish specification,
+ * the original RS definition used the polynomials,
+ * but that requires much more mathematical knowledge.
+ * We were already using matrix multiplication in a finite field for
+ * the MDS matrix, so I re-wrote the RS operation as a matrix
+ * multiplication to reduce the difficulty of understanding it.
+ * Some implementors have not picked up on this simpler method of
+ * computing the RS operation, even though it is mentioned in the
+ * specifications.
+ *
+ * It is possible to perform these computations faster by using 32-bit
+ * word operations, but that is not portable and this is not a speed-
+ * critical area.
+ *
+ * We explained the 1/x computation when we did the MDS matrix.
+ *
+ * The S vector is stored in K[32..64].
+ * The S vector has to be reversed, so we loop cross-wise.
+ *
+ * Note the weird byte spacing of the S-vector, to match the even
+ * or odd key words arrays. See the discussion at the Hxx macros for
+ * details.
+ */
+ kptr = K + 8*kCycles; /* Start at end of key */
+ sptr = K + 32; /* Start at start of S */
+
+ /* Loop over all key material */
+ while( kptr > K )
+ {
+ kptr -= 8;
+ /*
+ * Initialise the polynimial in sptr[0..12]
+ * The first four coefficients are 0 as we have to multiply by y^4.
+ * The next 8 coefficients are from the key material.
+ */
+ memset( sptr, 0, 4 );
+ memcpy( sptr+4, kptr, 8 );
+
+ /*
+ * The 12 bytes starting at sptr are now the coefficients of
+ * the polynomial we need to reduce.
+ */
+
+ /* Loop over the polynomial coefficients from high to low */
+ t = sptr+11;
+ /* Keep looping until polynomial is degree 3; */
+ while( t > sptr+3 )
+ {
+ /* Pick up the highest coefficient of the poly. */
+ b = *t;
+
+ /*
+ * Compute x and (x+1/x) times this coefficient.
+ * See the MDS matrix implementation for a discussion of
+ * multiplication by x and 1/x. We just use different
+ * constants here as we are in a
+ * different finite field representation.
+ *
+ * These two statements set
+ * bx = (x) * b
+ * bxx= (x + 1/x) * b
+ */
+ bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]);
+ bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx);
+
+ /*
+ * Subtract suitable multiple of
+ * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1
+ * from the polynomial, except that we don't bother
+ * updating t[0] as it will become zero anyway.
+ */
+ t[-1] ^= bxx;
+ t[-2] ^= bx;
+ t[-3] ^= bxx;
+ t[-4] ^= b;
+
+ /* Go to the next coefficient. */
+ t--;
+ }
+
+ /* Go to next S-vector word, obeying the weird spacing rules. */
+ sptr += 8;
+ }
+
+ /* Wipe variables that contained key material. */
+ b = bx = bxx = 0;
+
+ /* And finally, we can compute the key-dependent S-boxes. */
+ fill_keyed_sboxes( &K[32], kCycles, xkey );
+
+ /* Wipe array that contained key material. */
+ memset( K, 0, sizeof( K ) );
+ return SUCCESS;
+ }
+
+
+/*
+ * We can now start on the actual encryption and decryption code.
+ * As these are often speed-critical we will use a lot of macros.
+ */
+
+/*
+ * The g() function is the heart of the round function.
+ * We have two versions of the g() function, one without an input
+ * rotation and one with.
+ * The pre-computed S-boxes make this pretty simple.
+ */
+#define g0(X,xkey) \
+ (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)])
+
+#define g1(X,xkey) \
+ (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)])
+
+/*
+ * A single round of Twofish. The A,B,C,D are the four state variables,
+ * T0 and T1 are temporaries, xkey is the expanded key, and r the
+ * round number.
+ *
+ * Note that this macro does not implement the swap at the end of the round.
+ */
+#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
+ T0 = g0(A,xkey); T1 = g1(B,xkey);\
+ C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\
+ D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1]
+
+/*
+ * Encrypt a single cycle, consisting of two rounds.
+ * This avoids the swapping of the two halves.
+ * Parameter r is now the cycle number.
+ */
+#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
+ ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r) );\
+ ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 )
+
+/* Full 16-round encryption */
+#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
+ ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 )
+
+/*
+ * A single round of Twofish for decryption. It differs from
+ * ENCRYTP_RND only because of the 1-bit rotations.
+ */
+#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
+ T0 = g0(A,xkey); T1 = g1(B,xkey);\
+ C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\
+ D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1)
+
+/*
+ * Decrypt a single cycle, consisting of two rounds.
+ * This avoids the swapping of the two halves.
+ * Parameter r is now the cycle number.
+ */
+#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
+ DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\
+ DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r) )
+
+/* Full 16-round decryption. */
+#define DECRYPT( A,B,C,D,T0,T1, xkey ) \
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
+ DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 )
+
+/*
+ * A macro to read the state from the plaintext and do the initial key xors.
+ * The koff argument allows us to use the same macro
+ * for the decryption which uses different key words at the start.
+ */
+#define GET_INPUT( src, A,B,C,D, xkey, koff ) \
+ A = GET32(src )^xkey->K[ koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \
+ C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff]
+
+/*
+ * Similar macro to put the ciphertext in the output buffer.
+ * We xor the keys into the state variables before we use the PUT32
+ * macro as the macro might use its argument multiple times.
+ */
+#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \
+ A ^= xkey->K[ koff]; B ^= xkey->K[1+koff]; \
+ C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \
+ PUT32( A, dst ); PUT32( B, dst+ 4 ); \
+ PUT32( C, dst+8 ); PUT32( D, dst+12 )
+
+
+/*
+ * Twofish block encryption
+ *
+ * Arguments:
+ * xkey expanded key array
+ * p 16 bytes of plaintext
+ * c 16 bytes in which to store the ciphertext
+ */
+void Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16])
+ {
+ Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */
+
+ /* Get the four plaintext words xorred with the key */
+ GET_INPUT( p, A,B,C,D, xkey, 0 );
+
+ /* Do 8 cycles (= 16 rounds) */
+ ENCRYPT( A,B,C,D,T0,T1,xkey );
+
+ /* Store them with the final swap and the output whitening. */
+ PUT_OUTPUT( C,D,A,B, c, xkey, 4 );
+ }
+
+
+/*
+ * Twofish block decryption.
+ *
+ * Arguments:
+ * xkey expanded key array
+ * p 16 bytes of plaintext
+ * c 16 bytes in which to store the ciphertext
+ */
+void Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16])
+ {
+ Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */
+
+ /* Get the four plaintext words xorred with the key */
+ GET_INPUT( c, A,B,C,D, xkey, 4 );
+
+ /* Do 8 cycles (= 16 rounds) */
+ DECRYPT( A,B,C,D,T0,T1,xkey );
+
+ /* Store them with the final swap and the output whitening. */
+ PUT_OUTPUT( C,D,A,B, p, xkey, 0 );
+ }
+
+/*
+ * Using the macros it is easy to make special routines for
+ * CBC mode, CTR mode etc. The only thing you might want to
+ * add is a XOR_PUT_OUTPUT which xors the outputs into the
+ * destinationa instead of overwriting the data. This requires
+ * a XOR_PUT32 macro as well, but that should all be trivial.
+ *
+ * I thought about including routines for the separate cipher
+ * modes here, but it is unclear which modes should be included,
+ * and each encryption or decryption routine takes up a lot of code space.
+ * Also, I don't have any test vectors for any cipher modes
+ * with Twofish.
+ */
+
+
diff --git a/jni/libzrtp/sources/cryptcommon/twofish.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/twofish.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
index 21d7e96..0c8b0d7 100755
--- a/jni/libzrtp/sources/cryptcommon/twofish.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
@@ -1,265 +1,265 @@
-/*
- * Fast, portable, and easy-to-use Twofish implementation,
- * Version 0.3.
- * Copyright (c) 2002 by Niels Ferguson.
- *
- * See the twofish.c file for the details of the how and why of this code.
- *
- * The author hereby grants a perpetual license to everybody to
- * use this code for any purpose as long as the copyright message is included
- * in the source code of this or any derived work.
- */
-
-
-/*
- * PLATFORM FIXES
- * ==============
- *
- * The following definitions have to be fixed for each particular platform
- * you work on. If you have a multi-platform program, you no doubt have
- * portable definitions that you can substitute here without changing
- * the rest of the code.
- *
- * The defaults provided here should work on most PC compilers.
- */
-
-#ifndef TWOFISH_H
-#define TWOFISH_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @file twofish.h
- * @brief Function that provide basic Twofish crypto support
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * A Twofish_Byte must be an unsigned 8-bit integer.
- *
- * It must also be the elementary data size of your C platform,
- * i.e. sizeof( Twofish_Byte ) == 1.
- */
-typedef unsigned char Twofish_Byte;
-
-/**
- * A Twofish_UInt32 must be an unsigned integer of at least 32 bits.
- *
- * This type is used only internally in the implementation, so ideally it
- * would not appear in the header file, but it is used inside the
- * Twofish_key structure which means it has to be included here.
- */
-typedef unsigned int Twofish_UInt32;
-
-
-/*
- * END OF PLATFORM FIXES
- * =====================
- *
- * You should not have to touch the rest of this file, but the code
- * in twofish.c has a few things you need to fix too.
- */
-
-/**
- * Return codes
- */
-#define SUCCESS 1
-#define ERR_UINT32 -2
-#define ERR_BYTE -3
-#define ERR_GET32 -4
-#define ERR_PUT32 -5
-#define ERR_ROLR -6
-#define ERR_BSWAP -7
-#define ERR_SELECTB -8
-#define ERR_TEST_ENC -9
-#define ERR_TEST_DEC -10
-#define ERR_SEQ_ENC -11
-#define ERR_SEQ_DEC -12
-#define ERR_ODD_KEY -13
-#define ERR_INIT -14
-#define ERR_KEY_LEN -15
-#define ERR_ILL_ARG -16
-
-
-/**
- * Structure that contains a prepared Twofish key.
- *
- * A cipher key is used in two stages. In the first stage it is converted
- * form the original form to an internal representation.
- * This internal form is then used to encrypt and decrypt data.
- * This structure contains the internal form. It is rather large: 4256 bytes
- * on a platform with 32-bit unsigned values.
- *
- * Treat this as an opague structure, and don't try to manipulate the
- * elements in it. I wish I could hide the inside of the structure,
- * but C doesn't allow that.
- */
-typedef
- struct
- {
- Twofish_UInt32 s[4][256]; /* pre-computed S-boxes */
- Twofish_UInt32 K[40]; /* Round key words */
- }
- Twofish_key;
-
-
-/**
- * Initialise and test the Twofish implementation.
- *
- * This function MUST be called before any other function in the
- * Twofish implementation is called.
- * It only needs to be called once.
- *
- * Apart from initialising the implementation it performs a self test.
- * If the Twofish_fatal function is not called, the code passed the test.
- * (See the twofish.c file for details on the Twofish_fatal function.)
- *
- * @returns a negative number if an error happend, +1 otherwise
- */
-extern int Twofish_initialise();
-
-
-/**
- * Convert a cipher key to the internal form used for
- * encryption and decryption.
- *
- * The cipher key is an array of bytes; the Twofish_Byte type is
- * defined above to a type suitable on your platform.
- *
- * Any key must be converted to an internal form in the Twofisk_key structure
- * before it can be used.
- * The encryption and decryption functions only work with the internal form.
- * The conversion to internal form need only be done once for each key value.
- *
- * Be sure to wipe all key storage, including the Twofish_key structure,
- * once you are done with the key data.
- * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine.
- *
- * Unlike most implementations, this one allows any key size from 0 bytes
- * to 32 bytes. According to the Twofish specifications,
- * irregular key sizes are handled by padding the key with zeroes at the end
- * until the key size is 16, 24, or 32 bytes, whichever
- * comes first. Note that each key of irregular size is equivalent to exactly
- * one key of 16, 24, or 32 bytes.
- *
- * WARNING: Short keys have low entropy, and result in low security.
- * Anything less than 8 bytes is utterly insecure. For good security
- * use at least 16 bytes. I prefer to use 32-byte keys to prevent
- * any collision attacks on the key.
- *
- * The key length argument key_len must be in the proper range.
- * If key_len is not in the range 0,...,32 this routine attempts to generate
- * a fatal error (depending on the code environment),
- * and at best (or worst) returns without having done anything.
- *
- * @param key Array of key bytes
- * @param key_len Number of key bytes, must be in the range 0,1,...,32.
- * @param xkey Pointer to an Twofish_key structure that will be filled
- * with the internal form of the cipher key.
- * @returns a negative number if an error happend, +1 otherwise
- */
-extern int Twofish_prepare_key(
- Twofish_Byte key[],
- int key_len,
- Twofish_key * xkey
- );
-
-
-/**
- * Encrypt a single block of data.
- *
- * This function encrypts a single block of 16 bytes of data.
- * If you want to encrypt a larger or variable-length message,
- * you will have to use a cipher mode, such as CBC or CTR.
- * These are outside the scope of this implementation.
- *
- * The xkey structure is not modified by this routine, and can be
- * used for further encryption and decryption operations.
- *
- * @param xkey pointer to Twofish_key, internal form of the key
- * produces by Twofish_prepare_key()
- * @param p Plaintext to be encrypted
- * @param c Place to store the ciphertext
- */
-extern void Twofish_encrypt(
- Twofish_key * xkey,
- Twofish_Byte p[16],
- Twofish_Byte c[16]
- );
-
-
-/**
- * Decrypt a single block of data.
- *
- * This function decrypts a single block of 16 bytes of data.
- * If you want to decrypt a larger or variable-length message,
- * you will have to use a cipher mode, such as CBC or CTR.
- * These are outside the scope of this implementation.
- *
- * The xkey structure is not modified by this routine, and can be
- * used for further encryption and decryption operations.
- *
- * @param xkey pointer to Twofish_key, internal form of the key
- * produces by Twofish_prepare_key()
- * @param c Ciphertext to be decrypted
- * @param p Place to store the plaintext
- */
-extern void Twofish_decrypt(
- Twofish_key * xkey,
- Twofish_Byte c[16],
- Twofish_Byte p[16]
- );
-
-
-/**
- * Encrypt data in CFB mode.
- *
- * This function encrypts data in CFB mode.
- *
- * The key structure is not modified by this routine, and can be
- * used for further encryption and decryption operations.
- *
- * @param keyCtx pointer to Twofish_key, internal form of the key
- * produced by Twofish_prepare_key()
- * @param in Plaintext to be encrypted
- * @param out Place to store the ciphertext
- * @param len number of bytes to encrypt.
- * @param ivec initialization vector for this CFB mode encryption.
- * @param num pointer to integer that holds number of available crypto bytes.
- */
-void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,
- Twofish_Byte* out, size_t len,
- Twofish_Byte* ivec, int *num);
-
-/**
- * Decrypt data in CFB mode.
- *
- * This function decrypts data in CFB.
- *
- * The key structure is not modified by this routine, and can be
- * used for further encryption and decryption operations.
- *
- * @param keyCtx pointer to Twofish_key, internal form of the key
- * produced by Twofish_prepare_key()
- * @param in Ciphertext to be decrypted
- * @param out Place to store the plaintext
- * @param len number of bytes to decrypt.
- * @param ivec initialization vector for this CFB mode encryption.
- * @param num pointer to integer that holds number of available crypto bytes.
- */
-void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,
- Twofish_Byte* out, size_t len,
- Twofish_Byte* ivec, int *num);
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Fast, portable, and easy-to-use Twofish implementation,
+ * Version 0.3.
+ * Copyright (c) 2002 by Niels Ferguson.
+ *
+ * See the twofish.c file for the details of the how and why of this code.
+ *
+ * The author hereby grants a perpetual license to everybody to
+ * use this code for any purpose as long as the copyright message is included
+ * in the source code of this or any derived work.
+ */
+
+
+/*
+ * PLATFORM FIXES
+ * ==============
+ *
+ * The following definitions have to be fixed for each particular platform
+ * you work on. If you have a multi-platform program, you no doubt have
+ * portable definitions that you can substitute here without changing
+ * the rest of the code.
+ *
+ * The defaults provided here should work on most PC compilers.
+ */
+
+#ifndef TWOFISH_H
+#define TWOFISH_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file twofish.h
+ * @brief Function that provide basic Twofish crypto support
+ *
+ * @ingroup GNU_ZRTP
+ * @{
+ */
+
+/**
+ * A Twofish_Byte must be an unsigned 8-bit integer.
+ *
+ * It must also be the elementary data size of your C platform,
+ * i.e. sizeof( Twofish_Byte ) == 1.
+ */
+typedef unsigned char Twofish_Byte;
+
+/**
+ * A Twofish_UInt32 must be an unsigned integer of at least 32 bits.
+ *
+ * This type is used only internally in the implementation, so ideally it
+ * would not appear in the header file, but it is used inside the
+ * Twofish_key structure which means it has to be included here.
+ */
+typedef unsigned int Twofish_UInt32;
+
+
+/*
+ * END OF PLATFORM FIXES
+ * =====================
+ *
+ * You should not have to touch the rest of this file, but the code
+ * in twofish.c has a few things you need to fix too.
+ */
+
+/**
+ * Return codes
+ */
+#define SUCCESS 1
+#define ERR_UINT32 -2
+#define ERR_BYTE -3
+#define ERR_GET32 -4
+#define ERR_PUT32 -5
+#define ERR_ROLR -6
+#define ERR_BSWAP -7
+#define ERR_SELECTB -8
+#define ERR_TEST_ENC -9
+#define ERR_TEST_DEC -10
+#define ERR_SEQ_ENC -11
+#define ERR_SEQ_DEC -12
+#define ERR_ODD_KEY -13
+#define ERR_INIT -14
+#define ERR_KEY_LEN -15
+#define ERR_ILL_ARG -16
+
+
+/**
+ * Structure that contains a prepared Twofish key.
+ *
+ * A cipher key is used in two stages. In the first stage it is converted
+ * form the original form to an internal representation.
+ * This internal form is then used to encrypt and decrypt data.
+ * This structure contains the internal form. It is rather large: 4256 bytes
+ * on a platform with 32-bit unsigned values.
+ *
+ * Treat this as an opague structure, and don't try to manipulate the
+ * elements in it. I wish I could hide the inside of the structure,
+ * but C doesn't allow that.
+ */
+typedef
+ struct
+ {
+ Twofish_UInt32 s[4][256]; /* pre-computed S-boxes */
+ Twofish_UInt32 K[40]; /* Round key words */
+ }
+ Twofish_key;
+
+
+/**
+ * Initialise and test the Twofish implementation.
+ *
+ * This function MUST be called before any other function in the
+ * Twofish implementation is called.
+ * It only needs to be called once.
+ *
+ * Apart from initialising the implementation it performs a self test.
+ * If the Twofish_fatal function is not called, the code passed the test.
+ * (See the twofish.c file for details on the Twofish_fatal function.)
+ *
+ * @returns a negative number if an error happend, +1 otherwise
+ */
+extern int Twofish_initialise();
+
+
+/**
+ * Convert a cipher key to the internal form used for
+ * encryption and decryption.
+ *
+ * The cipher key is an array of bytes; the Twofish_Byte type is
+ * defined above to a type suitable on your platform.
+ *
+ * Any key must be converted to an internal form in the Twofisk_key structure
+ * before it can be used.
+ * The encryption and decryption functions only work with the internal form.
+ * The conversion to internal form need only be done once for each key value.
+ *
+ * Be sure to wipe all key storage, including the Twofish_key structure,
+ * once you are done with the key data.
+ * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine.
+ *
+ * Unlike most implementations, this one allows any key size from 0 bytes
+ * to 32 bytes. According to the Twofish specifications,
+ * irregular key sizes are handled by padding the key with zeroes at the end
+ * until the key size is 16, 24, or 32 bytes, whichever
+ * comes first. Note that each key of irregular size is equivalent to exactly
+ * one key of 16, 24, or 32 bytes.
+ *
+ * WARNING: Short keys have low entropy, and result in low security.
+ * Anything less than 8 bytes is utterly insecure. For good security
+ * use at least 16 bytes. I prefer to use 32-byte keys to prevent
+ * any collision attacks on the key.
+ *
+ * The key length argument key_len must be in the proper range.
+ * If key_len is not in the range 0,...,32 this routine attempts to generate
+ * a fatal error (depending on the code environment),
+ * and at best (or worst) returns without having done anything.
+ *
+ * @param key Array of key bytes
+ * @param key_len Number of key bytes, must be in the range 0,1,...,32.
+ * @param xkey Pointer to an Twofish_key structure that will be filled
+ * with the internal form of the cipher key.
+ * @returns a negative number if an error happend, +1 otherwise
+ */
+extern int Twofish_prepare_key(
+ Twofish_Byte key[],
+ int key_len,
+ Twofish_key * xkey
+ );
+
+
+/**
+ * Encrypt a single block of data.
+ *
+ * This function encrypts a single block of 16 bytes of data.
+ * If you want to encrypt a larger or variable-length message,
+ * you will have to use a cipher mode, such as CBC or CTR.
+ * These are outside the scope of this implementation.
+ *
+ * The xkey structure is not modified by this routine, and can be
+ * used for further encryption and decryption operations.
+ *
+ * @param xkey pointer to Twofish_key, internal form of the key
+ * produces by Twofish_prepare_key()
+ * @param p Plaintext to be encrypted
+ * @param c Place to store the ciphertext
+ */
+extern void Twofish_encrypt(
+ Twofish_key * xkey,
+ Twofish_Byte p[16],
+ Twofish_Byte c[16]
+ );
+
+
+/**
+ * Decrypt a single block of data.
+ *
+ * This function decrypts a single block of 16 bytes of data.
+ * If you want to decrypt a larger or variable-length message,
+ * you will have to use a cipher mode, such as CBC or CTR.
+ * These are outside the scope of this implementation.
+ *
+ * The xkey structure is not modified by this routine, and can be
+ * used for further encryption and decryption operations.
+ *
+ * @param xkey pointer to Twofish_key, internal form of the key
+ * produces by Twofish_prepare_key()
+ * @param c Ciphertext to be decrypted
+ * @param p Place to store the plaintext
+ */
+extern void Twofish_decrypt(
+ Twofish_key * xkey,
+ Twofish_Byte c[16],
+ Twofish_Byte p[16]
+ );
+
+
+/**
+ * Encrypt data in CFB mode.
+ *
+ * This function encrypts data in CFB mode.
+ *
+ * The key structure is not modified by this routine, and can be
+ * used for further encryption and decryption operations.
+ *
+ * @param keyCtx pointer to Twofish_key, internal form of the key
+ * produced by Twofish_prepare_key()
+ * @param in Plaintext to be encrypted
+ * @param out Place to store the ciphertext
+ * @param len number of bytes to encrypt.
+ * @param ivec initialization vector for this CFB mode encryption.
+ * @param num pointer to integer that holds number of available crypto bytes.
+ */
+void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,
+ Twofish_Byte* out, size_t len,
+ Twofish_Byte* ivec, int *num);
+
+/**
+ * Decrypt data in CFB mode.
+ *
+ * This function decrypts data in CFB.
+ *
+ * The key structure is not modified by this routine, and can be
+ * used for further encryption and decryption operations.
+ *
+ * @param keyCtx pointer to Twofish_key, internal form of the key
+ * produced by Twofish_prepare_key()
+ * @param in Ciphertext to be decrypted
+ * @param out Place to store the plaintext
+ * @param len number of bytes to decrypt.
+ * @param ivec initialization vector for this CFB mode encryption.
+ * @param num pointer to integer that holds number of available crypto bytes.
+ */
+void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,
+ Twofish_Byte* out, size_t len,
+ Twofish_Byte* ivec, int *num);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
similarity index 66%
rename from jni/libzrtp/sources/cryptcommon/twofish_cfb.c
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
index 241b956..7540738 100755
--- a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
@@ -1,94 +1,82 @@
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "twofish.h"
-
-void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,
- Twofish_Byte* out, size_t len,
- Twofish_Byte* ivec, int32_t *num)
-{
- uint32_t n;
-
- n = *num;
-
- do {
- while (n && len) {
- *(out++) = ivec[n] ^= *(in++);
- --len;
- n = (n+1) % 16;
- }
- while (len>=16) {
- Twofish_encrypt(keyCtx, ivec, ivec);
- for (n=0; n<16; n+=sizeof(size_t)) {
-
-/*
- * Some GCC version(s) of Android's NDK produce code that leads to a crash (SIGBUS). The
- * offending line if the line that produces the output by xor'ing the ivec. Somehow the
- * compiler/optimizer seems to incorrectly setup the pointers. Adding a call to an
- * external function that uses the pointer disabled or modifies this optimzing
- * behaviour. This debug functions as such does nothing, it just disables some
- * optimization. Don't use a local (static) function - the compiler sees that it does
- * nothing and optimizes again :-) .
- */
-#ifdef ANDROID
- Two_debugDummy(in, out, ivec);
-#endif
- *(size_t*)(out+n) = *(size_t*)(ivec+n) ^= *(size_t*)(in+n);;
- }
- len -= 16;
- out += 16;
- in += 16;
- }
- n = 0;
- if (len) {
- Twofish_encrypt(keyCtx, ivec, ivec);
- while (len--) {
- out[n] = ivec[n] ^= in[n];
- ++n;
- }
- }
- *num = n;
- return;
- } while (0);
-}
-
-
-void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,
- Twofish_Byte* out, size_t len,
- Twofish_Byte* ivec, int32_t *num)
-{
- uint32_t n;
-
- n = *num;
-
- do {
- while (n && len) {
- unsigned char c;
- *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
- --len;
- n = (n+1) % 16;
- }
- while (len>=16) {
- Twofish_encrypt(keyCtx, ivec, ivec);
- for (n=0; n<16; n+=sizeof(size_t)) {
- size_t t = *(size_t*)(in+n);
- *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
- *(size_t*)(ivec+n) = t;
- }
- len -= 16;
- out += 16;
- in += 16;
- }
- n = 0;
- if (len) {
- Twofish_encrypt(keyCtx, ivec, ivec);
- while (len--) {
- unsigned char c;
- out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
- ++n;
- }
- }
- *num = n;
- return;
- } while (0);
-}
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "twofish.h"
+
+void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,
+ Twofish_Byte* out, size_t len,
+ Twofish_Byte* ivec, int32_t *num)
+{
+ uint32_t n;
+
+ n = *num;
+
+ do {
+ while (n && len) {
+ *(out++) = ivec[n] ^= *(in++);
+ --len;
+ n = (n+1) % 16;
+ }
+ while (len>=16) {
+ Twofish_encrypt(keyCtx, ivec, ivec);
+ for (n=0; n<16; n+=sizeof(size_t)) {
+ *(size_t*)(out+n) =
+ *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
+ }
+ len -= 16;
+ out += 16;
+ in += 16;
+ }
+ n = 0;
+ if (len) {
+ Twofish_encrypt(keyCtx, ivec, ivec);
+ while (len--) {
+ out[n] = ivec[n] ^= in[n];
+ ++n;
+ }
+ }
+ *num = n;
+ return;
+ } while (0);
+}
+
+
+void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,
+ Twofish_Byte* out, size_t len,
+ Twofish_Byte* ivec, int32_t *num)
+{
+ uint32_t n;
+
+ n = *num;
+
+ do {
+ while (n && len) {
+ unsigned char c;
+ *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
+ --len;
+ n = (n+1) % 16;
+ }
+ while (len>=16) {
+ Twofish_encrypt(keyCtx, ivec, ivec);
+ for (n=0; n<16; n+=sizeof(size_t)) {
+ size_t t = *(size_t*)(in+n);
+ *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
+ *(size_t*)(ivec+n) = t;
+ }
+ len -= 16;
+ out += 16;
+ in += 16;
+ }
+ n = 0;
+ if (len) {
+ Twofish_encrypt(keyCtx, ivec, ivec);
+ while (len--) {
+ unsigned char c;
+ out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
+ ++n;
+ }
+ }
+ *num = n;
+ return;
+ } while (0);
+}
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h b/jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
rename to jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
index f01fb52..18ba7a1 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h b/jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
rename to jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
index 3eae183..d94ca5a 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
@@ -19,7 +19,7 @@
#define _ZRTPCCRTP_H_
#include <ccrtp/rtp.h>
-#include <ZrtpQueue.h>
+#include <libzrtpcpp/ZrtpQueue.h>
NAMESPACE_COMMONCPP
diff --git a/jni/libzrtp/sources/srtp/CryptoContext.cpp b/jni/libzrtp/sources/srtp/CryptoContext.cpp
index 89eb699..d486f86 100644
--- a/jni/libzrtp/sources/srtp/CryptoContext.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContext.cpp
@@ -1,6 +1,4 @@
/*
- Copyright (C) 2006 - 2012 Werner Dittmann
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@@ -16,20 +14,22 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/*
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+/* Copyright (C) 2004-2012
+ *
+ * Authors: Israel Abad <i_abad@terra.es>
+ * Erik Eliasson <eliasson@it.kth.se>
+ * Johan Bilien <jobi@via.ecp.fr>
+ * Joachim Orrblad <joachim@orrblad.com>
+ * Werner Dittmann <Werner.Dittmann@t-online.de>
*/
#include <string.h>
+#include <arpa/inet.h>
#include <stdio.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
#include <CryptoContext.h>
-#include <crypto/SrtpSymCrypto.h>
#include <crypto/hmac.h>
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
CryptoContext::CryptoContext( uint32_t ssrc,
int32_t roc,
@@ -45,10 +45,11 @@
int32_t skeyl,
int32_t tagLength):
- ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL), roc(roc),guessed_roc(0),
- s_l(0),key_deriv_rate(key_deriv_rate), replay_window(0), master_key_srtp_use_nb(0),
- master_key_srtcp_use_nb(0), labelBase(0), seqNumSet(false), macCtx(NULL), cipher(NULL),
- f8Cipher(NULL)
+ ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL),
+ roc(roc),guessed_roc(0),s_l(0),key_deriv_rate(key_deriv_rate),
+ replay_window(0),
+ master_key_srtp_use_nb(0), master_key_srtcp_use_nb(0), seqNumSet(false),
+ macCtx(NULL), cipher(NULL), f8Cipher(NULL)
{
this->ealg = ealg;
this->aalg = aalg;
@@ -188,7 +189,7 @@
iv[i] = (0xFF & (ssrc >> ((7-i)*8))) ^ k_s[i];
}
for (i = 8; i < 14; i++ ) {
- iv[i] = (0xFF & (unsigned char)(index >> ((13-i)*8) ) ) ^ k_s[i];
+ iv[i] = (0xFF & (unsigned char)( index >> ((13-i)*8) ) ) ^ k_s[i];
}
iv[14] = iv[15] = 0;
@@ -212,7 +213,7 @@
iv[0] = 0;
// set ROC in network order into IV
- ui32p[3] = zrtpHtonl(roc);
+ ui32p[3] = htonl(roc);
cipher->f8_encrypt(payload, paylen, iv, f8Cipher);
}
@@ -230,7 +231,7 @@
unsigned char temp[20];
const unsigned char* chunks[3];
unsigned int chunkLength[3];
- uint32_t beRoc = zrtpHtonl(roc);
+ uint32_t beRoc = htonl(roc);
chunks[0] = pkt;
chunkLength[0] = pktlen;
@@ -288,8 +289,10 @@
}
for (i = 7; i < 14 ; i++ ) {
- iv[i] = (unsigned char)(0xFF & (key_id >> (8*(13-i)))) ^ master_salt[i];
+ iv[i] = (unsigned char)(0xFF & (key_id >> (8*(13-i)))) ^
+ master_salt[i];
}
+
iv[14] = iv[15] = 0;
}
@@ -298,17 +301,17 @@
{
uint8_t iv[16];
- // prepare cipher to compute derived keys.
+ // prepare AES cipher to compute derived keys.
cipher->setNewKey(master_key, master_key_length);
memset(master_key, 0, master_key_length);
// compute the session encryption key
- uint64_t label = labelBase + 0;
+ uint64_t label = 0;
computeIv(iv, label, index, key_deriv_rate, master_salt);
cipher->get_ctr_cipher_stream(k_e, n_e, iv);
// compute the session authentication key
- label = labelBase + 0x01;
+ label = 0x01;
computeIv(iv, label, index, key_deriv_rate, master_salt);
cipher->get_ctr_cipher_stream(k_a, n_a, iv);
@@ -325,12 +328,12 @@
memset(k_a, 0, n_a);
// compute the session salt
- label = labelBase + 0x02;
+ label = 0x02;
computeIv(iv, label, index, key_deriv_rate, master_salt);
cipher->get_ctr_cipher_stream(k_s, n_s, iv);
memset(master_salt, 0, master_salt_length);
- // as last step prepare cipher with derived key.
+ // as last step prepare AES cipher with derived key.
cipher->setNewKey(k_e, n_e);
if (f8Cipher != NULL)
cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);
@@ -388,18 +391,22 @@
int64_t delta = guessed_index - local_index;
if (delta > 0) {
- return true; /* Packet not yet received*/
+ /* Packet not yet received*/
+ return true;
}
else {
- if ( -delta >= REPLAY_WINDOW_SIZE ) {
- return false; /* Packet too old */
+ if ( -delta > REPLAY_WINDOW_SIZE ) {
+ /* Packet too old */
+ return false;
}
else {
if ((replay_window >> (-delta)) & 0x1) {
- return false; /* Packet already received ! */
+ /* Packet already received ! */
+ return false;
}
else {
- return true; /* Packet not yet received */
+ /* Packet not yet received */
+ return true;
}
}
}
@@ -447,3 +454,12 @@
return pcc;
}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContext.h b/jni/libzrtp/sources/srtp/CryptoContext.h
index 25c3a08..3075bf5 100644
--- a/jni/libzrtp/sources/srtp/CryptoContext.h
+++ b/jni/libzrtp/sources/srtp/CryptoContext.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2006 - 2012 Werner Dittmann
+ Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+
#ifndef CRYPTOCONTEXT_H
#define CRYPTOCONTEXT_H
@@ -38,21 +40,21 @@
const int SrtpEncryptionTWOCM = 3;
const int SrtpEncryptionTWOF8 = 4;
-// Check if included via CryptoContextCtrl.cpp - avoid double definitions
#ifndef CRYPTOCONTEXTCTRL_H
#include <stdint.h>
+#include <crypto/SrtpSymCrypto.h>
class SrtpSymCrypto;
/**
- * @brief Implementation for a SRTP cryptographic context.
+ * The implementation for a SRTP cryptographic context.
*
* This class holds data and provides functions that implement a
- * cryptographic context for SRTP. Refer to RFC 3711, chapter 3.2 for some
+ * cryptographic context for SRTP, Refer to RFC 3711, chapter 3.2 for some
* more detailed information about the SRTP cryptographic context.
*
- * Each SRTP cryptographic context uses a RTP source identified by
+ * Each SRTP cryptographic context maintains a RTP source identified by
* its SSRC. Thus you can independently protect each source inside a RTP
* session.
*
@@ -60,93 +62,35 @@
* cryptographic context, such as master key, key length, authentication
* length and so on. The key management mechanisms are not part of
* SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
- * (RFC6189). After key management negotiated the data the application can
- * setup the SRTP cryptographic context and enable SRTP processing.
+ * (draft-zimmermann-avt-zrtp-01). After key management negotiated the
+ * data the application can setup the SRTP cryptographic context and
+ * enable SRTP processing.
*
- * This SRTP context implementation supports RTP only.
+ * Currently this implementation supports RTP only, not RTCP.
*
- * A short eample how to setup a SRTP CryptoContext:
- @verbatim
-
- // First some key and salt data - this data is just for demo purposes
- uint8 masterKey[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
-
- uint8 masterSalt[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d };
-
- ...
-
- CryptoContext* cryptoCtxSend =
- new CryptoContext(0xfeedbacc,
- 0, // roc,
- 0L, // keyderivation rate << 48,
- SrtpEncryptionAESCM, // encryption algo
- SrtpAuthenticationSha1Hmac, // authtication algo
- masterKey, // Master Key data
- 128 / 8, // Master Key length in bytes
- masterSalt, // Master Salt data
- 112 / 8, // Master Salt length in bytes
- 128 / 8, // encryption keylength in bytes
- 160 / 8, // authentication key length in bytes (SHA1)
- 112 / 8, // session salt length in bytes
- 80 / 8); // authentication tag length in bytes
-
- cryptoCtxSend->deriveSrtpKeys(0);
-
- ....
-
- // To protect a RTP packet
- // buffer: pointer to the RTP packet, length of the RTP data, newLength is a
- // pointer to a size_t that gets the updated length.
- bool rc = SrtpHandler::protect(cryptoCtxSend, buffer, length, newLength);
-
- // To unprotect a SRTP packet:
- // buffer: pointer to the RTP packet, length of the SRTP data, newLength is a
- // pointer to a size_t that gets the updated length.
- int32_t rc = SrtpHandler::unprotect(cryptoCtxRecv, buffer, length, newLength);
-
- @endverbatim
- *
- * @note You need two CryptoContext instances - one for the sending channel the
- * other one for the receiving channel.
- *
- * Before an appliction can use a CryptoContext it must call the key derivation
- * function deriveSrtpKeys() first. Only then this SRTP cryptographic context is ready
- * to protect or unprotect a RTP SSRC stream.
- *
- * Together with the newCryptoContextForSSRC() function an application can prepare a
- * CryptoContext and save it as template. Once it needs a new CryptoContext, say
- * for a new SSRC, it calls newCryptoContextForSSRC() on the saved context to get an
- * initialized copy and then call deriveSrtpKeys() to compute and process the keys.
- *
- * @note A saved, pre-initialized template contains the non-processed keys. Only
- * the method deriveSrtpKeys() processes the keys and cleares them. Thus don't store
- * CryptoContext templates if the application cannot protect the templates against
- * reading from other possibly rogue applications.
- *
- * @sa SrtpHandler
- *
+ * @author Israel Abad <i_abad@terra.es>
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
+ * @author Joachim Orrblad <joachim@orrblad.com>
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
+
class CryptoContext {
public:
/**
- * @brief Constructor for an active SRTP cryptographic context.
+ * Constructor for an active SRTP cryptographic context.
*
- * This constructor creates an pre-initialized SRTP cryptographic context were
- * algorithms are allocated, keys are stored and so on. An application can
- * call newCryptoContextForSSRC() to get a full copy of this pre-initialized
- * CryptoContext.
- *
+ * This constructor creates an active SRTP cryptographic context were
+ * algorithms are enabled, keys are computed and so on. This SRTP
+ * cryptographic context can protect a RTP SSRC stream.
*
* @param ssrc
- * The RTP SSRC that this SRTP cryptographic context belongs to.
+ * The RTP SSRC that this SRTP cryptographic context protects.
*
* @param roc
* The initial Roll-Over-Counter according to RFC 3711. These are the
- * upper 32 bit of the overall 48 bit SRTP packet index. Usually set to zero.
- * Refer to chapter 3.2.1 of the RFC.
+ * upper 32 bit of the overall 48 bit SRTP packet index. Refer to
+ * chapter 3.2.1 of the RFC.
*
* @param keyDerivRate
* The key derivation rate defines when to recompute the SRTP session
@@ -154,14 +98,15 @@
*
* @param ealg
* The encryption algorithm to use. Possible values are <code>
- * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
- * SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1
- * for AESCM (Counter mode) and 4.1.2 for AES F8 mode.
+ * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
+ * </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2
+ * for AES F8 mode.
*
* @param aalg
* The authentication algorithm to use. Possible values are <code>
- * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
- * </code>.
+ * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only
+ * active algorithm here is SHA1 HMAC, a SHA1 based hashed message
+ * authentication code as defined in RFC 2104.
*
* @param masterKey
* Pointer to the master key for this SRTP cryptographic context.
@@ -175,26 +120,27 @@
* bytes (128 or 256 bit master key)
*
* @param masterSalt
- * SRTP uses the master salt to generate the initialization vector
+ * SRTP uses the master salt to computer the initialization vector
* that in turn is input to compute the session key, session
* authentication key and the session salt.
*
* @param masterSaltLength
- * The length in bytes of the master salt data in bytes. According to
- * RFC3711 the standard value for the master salt length should
- * be 14 bytes (112 bit).
+ * The length in bytes of the master salt data in bytes. SRTP uses
+ * AES as encryption algorithm. AES encrypts 16 byte blocks
+ * (independent of the key length). According to RFC3711 the standard
+ * value for the master salt length should be 112 bit (14 bytes).
*
* @param ekeyl
* The length in bytes of the session encryption key that SRTP shall
- * generate and use. Usually the same length as for the master key
- * length, however you may use a different length as well.
+ * compute and use. Usually the same length as for the master key
+ * length. But you may use a different length as well. Be carefull
+ * that the key management mechanisms supports different key lengths.
*
* @param akeyl
* The length in bytes of the session authentication key. SRTP
* computes this key and uses it as input to the authentication
* algorithm.
- * This is usually 160 bits (20 bytes) for @c SrtpAuthenticationSha1Hmac
- * and 256 bits (32 bytes) for @c SrtpAuthenticationSkeinHmac.
+ * The standard value is 160 bits (20 bytes).
*
* @param skeyl
* The length in bytes of the session salt. SRTP computes this salt
@@ -203,11 +149,9 @@
*
* @param tagLength
* The length is bytes of the authentication tag that SRTP appends
- * to the RTP packet. The @c CryptoContext supports @c SrtpAuthenticationSha1Hmac
- * with 4 and 10 byte (32 and 80 bits) and @c SrtpAuthenticationSkeinHmac
- * with 4 and 8 bytes (32 and 64 bits) tag length. Refer to chapter 4.2. in RFC 3711.
+ * to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
*/
- CryptoContext(uint32_t ssrc, int32_t roc,
+ CryptoContext( uint32_t ssrc, int32_t roc,
int64_t keyDerivRate,
const int32_t ealg,
const int32_t aalg,
@@ -218,17 +162,16 @@
int32_t ekeyl,
int32_t akeyl,
int32_t skeyl,
- int32_t tagLength);
-
+ int32_t tagLength );
/**
- * @brief Destructor.
+ * Destructor.
*
* Cleans the SRTP cryptographic context.
*/
~CryptoContext();
/**
- * @brief Set the Roll-Over-Counter.
+ * Set the Roll-Over-Counter.
*
* Ths method sets the upper 32 bit of the 48 bit SRTP packet index
* (the roll-over-part)
@@ -236,20 +179,28 @@
* @param r
* The roll-over-counter
*/
- inline void setRoc(uint32_t r) { roc = r; }
+ inline void
+ setRoc(uint32_t r)
+ {
+ roc = r;
+ }
/**
- * @brief Get the Roll-Over-Counter.
+ * Get the Roll-Over-Counter.
*
* Ths method get the upper 32 bit of the 48 bit SRTP packet index
* (the roll-over-part)
*
* @return The roll-over-counter
*/
- inline uint32_t getRoc() const { return roc; }
+ inline uint32_t
+ getRoc() const
+ {
+ return roc;
+ }
/**
- * @brief Perform SRTP encryption.
+ * Perform SRTP encryption.
*
* This method encrypts <em>and</em> decrypts SRTP payload data. Plain
* data gets encrypted, encrypted data get decrypted.
@@ -270,10 +221,10 @@
* @param ssrc
* The RTP SSRC data in <em>host</em> order.
*/
- void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc);
+ void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc );
/**
- * @brief Compute the authentication tag.
+ * Compute the authentication tag.
*
* Compute the authentication tag according the the paramters in the
* SRTP Cryptograhic context.
@@ -291,26 +242,23 @@
* Points to a buffer that hold the computed tag. This buffer must
* be able to hold <code>tagLength</code> bytes.
*/
- void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag);
+ void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag );
/**
- * @brief Perform key derivation according to SRTP specification
+ * Perform key derivation according to SRTP specification
*
* This method computes the session key, session authentication key and the
* session salt key. This method must be called at least once after the
* SRTP Cryptograhic context was set up.
*
- * This method clears the key data once it was processed by the encryptions'
- * set key functions.
- *
* @param index
* The 48 bit SRTP packet index. See the <code>guessIndex</code>
- * method. Usually 0.
+ * method.
*/
void deriveSrtpKeys(uint64_t index);
/**
- * @brief Compute (guess) the new SRTP index based on the sequence number of
+ * Compute (guess) the new SRTP index based on the sequence number of
* a received RTP packet.
*
* The method uses the algorithm show in RFC3711, Appendix A, to compute
@@ -324,7 +272,7 @@
uint64_t guessIndex(uint16_t newSeqNumber);
/**
- * @brief Check for packet replay.
+ * Check for packet replay.
*
* The method check if a received packet is either to old or was already
* received.
@@ -341,7 +289,7 @@
bool checkReplay(uint16_t newSeqNumber);
/**
- * @brief Update the SRTP packet index.
+ * Update the SRTP packet index.
*
* Call this method after all checks were successful. See chapter
* 3.3.1 in the RFC when to update the ROC and ROC processing.
@@ -349,67 +297,64 @@
* @param newSeqNumber
* The sequence number of the received RTP packet in host order.
*/
- void update(uint16_t newSeqNumber);
+ void update( uint16_t newSeqNumber );
/**
- * @brief Get the length of the SRTP authentication tag in bytes.
+ * Get the length of the SRTP authentication tag in bytes.
*
* @return the length of the authentication tag.
*/
- int32_t getTagLength() const { return tagLength; }
+ inline int32_t
+ getTagLength() const
+ {
+ return tagLength;
+ }
+
/**
- * @brief Get the length of the MKI in bytes.
+ * Get the length of the MKI in bytes.
*
* @return the length of the MKI.
*/
- int32_t getMkiLength() const { return mkiLength; }
+ inline int32_t
+ getMkiLength() const
+ {
+ return mkiLength;
+ }
/**
- * @brief Get the SSRC of this SRTP Cryptograhic context.
+ * Get the SSRC of this SRTP Cryptograhic context.
*
* @return the SSRC.
*/
- uint32_t getSsrc() const { return ssrcCtx; }
+ inline uint32_t
+ getSsrc() const
+ {
+ return ssrcCtx;
+ }
/**
- * @brief Set the start (base) number to compute the PRF labels.
- *
- * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
- * CryptoContext computes the labes as follows:
- *
- * - labelBase + 0 -> encryption label
- * - labelBase + 1 -> authentication label
- * - labelBase + 2 -> salting key label
- *
- * The CryptoContext constructor initializes CryptoContext::labelBase
- * with 0 to comply with RFC 3711 label values.
- *
- * Applications may set the #labelBase to other values to use the CryptoContext
- * for other purposes.
- */
- void setLabelbase(uint8_t base) { labelBase = base; }
-
- /**
- * @brief Derive a new Crypto Context for use with a new SSRC
+ * Derive a new Crypto Context for use with a new SSRC
*
* This method returns a new Crypto Context initialized with the data
* of this crypto context. Replacing the SSRC, Roll-over-Counter, and
- * the key derivation rate the application can use this Crypto Context
+ * the key derivation rate the application cab use this Crypto Context
* to encrypt / decrypt a new stream (Synchronization source) inside
* one RTP session.
*
- * Before the application can use this crypto context it must call deriveSrtpKeys().
+ * Before the application can use this crypto context it must call
+ * the <code>deriveSrtpKeys</code> method.
*
* @param ssrc
* The SSRC for this context
* @param roc
- * The Roll-Over-Counter for this context, usually 0
+ * The Roll-Over-Counter for this context
* @param keyDerivRate
- * The key derivation rate for this context, usally 0
+ * The key derivation rate for this context
* @return
* a new CryptoContext with all relevant data set.
*/
+
CryptoContext* newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate);
private:
@@ -448,7 +393,6 @@
int32_t akeyl;
int32_t skeyl;
int32_t tagLength;
- uint8_t labelBase;
bool seqNumSet;
void* macCtx;
@@ -464,3 +408,11 @@
*/
#endif
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
index 952a823..caf5746 100644
--- a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2011 - 2012 Werner Dittmann
+ Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,22 +16,24 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/*
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+/* Copyright (C) 2004-2012
+ *
+ * Authors: Israel Abad <i_abad@terra.es>
+ * Erik Eliasson <eliasson@it.kth.se>
+ * Johan Bilien <jobi@via.ecp.fr>
+ * Joachim Orrblad <joachim@orrblad.com>
+ * Werner Dittmann <Werner.Dittmann@t-online.de>
*/
#include <string.h>
+#include <arpa/inet.h>
#include <stdio.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
#include <CryptoContextCtrl.h>
#include <CryptoContext.h>
-#include <crypto/SrtpSymCrypto.h>
#include <crypto/hmac.h>
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
CryptoContextCtrl::CryptoContextCtrl(uint32_t ssrc,
@@ -45,9 +47,8 @@
int32_t akeyl,
int32_t skeyl,
int32_t tagLength):
-ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL), replay_window(0), srtcpIndex(0),
-labelBase(3), macCtx(NULL), cipher(NULL), f8Cipher(NULL) // SRTCP labels start at 3
-
+ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL),
+replay_window(0), macCtx(NULL), cipher(NULL), f8Cipher(NULL)
{
this->ealg = ealg;
this->aalg = aalg;
@@ -163,7 +164,7 @@
aalg = SrtpAuthenticationNull;
}
-void CryptoContextCtrl::srtcpEncrypt( uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc )
+void CryptoContextCtrl::srtcpEncrypt( uint8_t* rtp, int32_t len, uint64_t index, uint32_t ssrc )
{
if (ealg == SrtpEncryptionNull) {
return;
@@ -243,7 +244,7 @@
unsigned char temp[20];
const unsigned char* chunks[3];
unsigned int chunkLength[3];
- uint32_t beIndex = zrtpHtonl(index);
+ uint32_t beIndex = htonl(index);
chunks[0] = rtp;
chunkLength[0] = len;
@@ -295,17 +296,17 @@
{
uint8_t iv[16];
- // prepare cipher to compute derived keys.
+ // prepare AES cipher to compute derived keys.
cipher->setNewKey(master_key, master_key_length);
memset(master_key, 0, master_key_length);
// compute the session encryption key
- uint8_t label = labelBase;
+ uint8_t label = 3;
computeIv(iv, label, master_salt);
cipher->get_ctr_cipher_stream(k_e, n_e, iv);
// compute the session authentication key
- label = labelBase + 1;
+ label = 4;
computeIv(iv, label, master_salt);
cipher->get_ctr_cipher_stream(k_a, n_a, iv);
@@ -322,12 +323,12 @@
memset(k_a, 0, n_a);
// compute the session salt
- label = labelBase + 2;
+ label = 5;
computeIv(iv, label, master_salt);
cipher->get_ctr_cipher_stream(k_s, n_s, iv);
memset(master_salt, 0, master_salt_length);
- // as last step prepare cipher with derived key.
+ // as last step prepare AES cipher with derived key.
cipher->setNewKey(k_e, n_e);
if (f8Cipher != NULL)
cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);
@@ -341,21 +342,24 @@
return true;
}
- int64_t delta = index - s_l;
+ int64_t delta = s_l - index;
if (delta > 0) {
/* Packet not yet received*/
return true;
}
else {
- if( -delta >= REPLAY_WINDOW_SIZE ) {
- return false; /* Packet too old */
+ if( -delta > REPLAY_WINDOW_SIZE ) {
+ /* Packet too old */
+ return false;
}
else {
if((replay_window >> (-delta)) & 0x1) {
- return false; /* Packet already received ! */
+ /* Packet already received ! */
+ return false;
}
else {
- return true; /* Packet not yet received */
+ /* Packet not yet received */
+ return true;
}
}
}
@@ -373,8 +377,7 @@
else {
replay_window |= ( 1 << delta );
}
- if (index > s_l)
- s_l = index;
+ s_l = index;
}
CryptoContextCtrl* CryptoContextCtrl::newCryptoContextForSSRC(uint32_t ssrc)
@@ -394,3 +397,12 @@
return pcc;
}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContextCtrl.h b/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
index 3adcd8d..456e58f 100644
--- a/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
+++ b/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
@@ -1,6 +1,7 @@
/*
- Copyright (C) 2011 - 2012 Werner Dittmann
-
+ Copyright (C) 2004-2006 the Minisip Team
+ Copyright (C) 2011 Werner Dittmann for the SRTCP support
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@@ -16,110 +17,117 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+
#ifndef CRYPTOCONTEXTCTRL_H
#define CRYPTOCONTEXTCTRL_H
/**
- * @file CryptoContextCtrl.h
- * @brief The C++ SRTCP implementation
+ * @file CryptoContext.h
+ * @brief The C++ SRTP implementation
* @ingroup Z_SRTP
* @{
*/
+#include <crypto/SrtpSymCrypto.h>
+
class SrtpSymCrypto;
-/**
- * The implementation for a SRTCP cryptographic context.
- *
- * This class holds data and provides functions that implement a
- * cryptographic context for SRTCP, Refer to RFC 3711, chapter 3.2 for some
- * more detailed information about the SRTCP cryptographic context.
- *
- * Each SRTCP cryptographic context maintains a RTCP source identified by
- * its SSRC. Thus you can independently protect each source inside a RTP
- * session.
- *
- * Key management mechanisms negotiate the parameters for the SRTCP
- * cryptographic context, such as master key, key length, authentication
- * length and so on. The key management mechanisms are not part of
- * SRTCP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
- * (RFC6189). After key management negotiated the data the application
- * can setup the SRTCP cryptographic context and enable SRTCP processing.
- *
- * @sa CryptoContext
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
+ /**
+ * The implementation for a SRTCP cryptographic context.
+ *
+ * This class holds data and provides functions that implement a
+ * cryptographic context for SRTP, Refer to RFC 3711, chapter 3.2 for some
+ * more detailed information about the SRTP cryptographic context.
+ *
+ * Each SRTP cryptographic context maintains a RTP source identified by
+ * its SSRC. Thus you can independently protect each source inside a RTP
+ * session.
+ *
+ * Key management mechanisms negotiate the parameters for the SRTP
+ * cryptographic context, such as master key, key length, authentication
+ * length and so on. The key management mechanisms are not part of
+ * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
+ * (draft-zimmermann-avt-zrtp-01). After key management negotiated the
+ * data the application can setup the SRTCP cryptographic context and
+ * enable SRTCP processing.
+ *
+ *
+ * @author Israel Abad <i_abad@terra.es>
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
+ * @author Joachim Orrblad <joachim@orrblad.com>
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
class CryptoContextCtrl {
public:
/**
- * @brief Constructor for an active SRTCP cryptographic context.
+ * Constructor for an active SRTP cryptographic context.
*
- * This constructor creates an active SRTCP cryptographic context were
- * algorithms are enabled, keys are computed and so on. This SRTCP
- * cryptographic context can protect a RTCP SSRC stream.
- *
- * See the notes in CryptoContext documentation regarding the handling
- * of key data.
+ * This constructor creates an active SRTP cryptographic context were
+ * algorithms are enabled, keys are computed and so on. This SRTP
+ * cryptographic context can protect a RTP SSRC stream.
*
* @param ssrc
- * The RTP SSRC that this SRTCP cryptographic context protects.
+ * The RTP SSRC that this SRTP cryptographic context protects.
*
* @param ealg
* The encryption algorithm to use. Possible values are <code>
- * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
+ * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
* </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2
* for AES F8 mode.
*
* @param aalg
* The authentication algorithm to use. Possible values are <code>
- * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
- * </code>.
+ * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only
+ * active algorithm here is SHA1 HMAC, a SHA1 based hashed message
+ * authentication code as defined in RFC 2104.
*
* @param masterKey
- * Pointer to the master key for this SRTCP cryptographic context.
+ * Pointer to the master key for this SRTP cryptographic context.
* Must point to <code>masterKeyLength</code> bytes. Refer to chapter
* 3.2.1 of the RFC about the role of the master key.
*
* @param masterKeyLength
* The length in bytes of the master key in bytes. The length must
- * match the selected encryption algorithm. Because SRTCP uses AES
+ * match the selected encryption algorithm. Because SRTP uses AES
* based encryption only, then master key length may be 16 or 32
* bytes (128 or 256 bit master key)
*
* @param masterSalt
- * SRTCP uses the master salt to computer the initialization vector
+ * SRTP uses the master salt to computer the initialization vector
* that in turn is input to compute the session key, session
* authentication key and the session salt.
*
* @param masterSaltLength
- * The length in bytes of the master salt data in bytes. SRTCP uses
+ * The length in bytes of the master salt data in bytes. SRTP uses
* AES as encryption algorithm. AES encrypts 16 byte blocks
* (independent of the key length). According to RFC3711 the standard
* value for the master salt length should be 112 bit (14 bytes).
*
* @param ekeyl
- * The length in bytes of the session encryption key that SRTCP shall
+ * The length in bytes of the session encryption key that SRTP shall
* compute and use. Usually the same length as for the master key
* length. But you may use a different length as well. Be carefull
* that the key management mechanisms supports different key lengths.
*
* @param akeyl
- * The length in bytes of the session authentication key. SRTCP
+ * The length in bytes of the session authentication key. SRTP
* computes this key and uses it as input to the authentication
* algorithm.
* The standard value is 160 bits (20 bytes).
*
* @param skeyl
- * The length in bytes of the session salt. SRTCP computes this salt
+ * The length in bytes of the session salt. SRTP computes this salt
* key and uses it as input during encryption. The length usually
* is the same as the master salt length.
*
* @param tagLength
- * The length is bytes of the authentication tag that SRTCP appends
+ * The length is bytes of the authentication tag that SRTP appends
* to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
*/
- CryptoContextCtrl(uint32_t ssrc,
+ CryptoContextCtrl( uint32_t ssrc,
const int32_t ealg,
const int32_t aalg,
uint8_t* masterKey,
@@ -129,71 +137,65 @@
int32_t ekeyl,
int32_t akeyl,
int32_t skeyl,
- int32_t tagLength);
-
+ int32_t tagLength );
/**
- * @brief Destructor.
+ * Destructor.
*
- * Cleans the SRTCP cryptographic context.
+ * Cleans the SRTP cryptographic context.
*/
~CryptoContextCtrl();
/**
- * @brief Perform SRTCP encryption.
+ * Perform SRTP encryption.
*
- * This method encrypts <em>and</em> decrypts SRTCP payload data. Plain
+ * This method encrypts <em>and</em> decrypts SRTP payload data. Plain
* data gets encrypted, encrypted data get decrypted.
*
* @param rtp
* The RTP packet that contains the data to encrypt.
*
- * @param len
- * Length of the RTCP packet
- *
* @param index
- * The 31 bit SRTCP packet index.
+ * The 48 bit SRTP packet index. See the <code>guessIndex</code>
+ * method.
*
* @param ssrc
- * The RTCP SSRC data in <em>host</em> order.
+ * The RTP SSRC data in <em>host</em> order.
*/
- void srtcpEncrypt(uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc);
+ void srtcpEncrypt( uint8_t* rtp, int32_t len, uint64_t index, uint32_t ssrc );
/**
- * @brief Compute the authentication tag.
+ * Compute the authentication tag.
*
* Compute the authentication tag according the the paramters in the
- * SRTCP Cryptograhic context.
+ * SRTP Cryptograhic context.
*
* @param rtp
- * The RTCP packet that contains the data to authenticate.
+ * The RTP packet that contains the data to authenticate.
*
- * @param len
- * Length of the RTCP packet
- *
- * @param index
- * The 31 bit SRTCP index.
+ * @param roc
+ * The 32 bit SRTP roll-over-counter.
*
* @param tag
* Points to a buffer that hold the computed tag. This buffer must
* be able to hold <code>tagLength</code> bytes.
*/
- void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag);
+ void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t roc, uint8_t* tag );
/**
- * @brief Perform key derivation according to SRTCP specification
+ * Perform key derivation according to SRTP specification
*
* This method computes the session key, session authentication key and the
* session salt key. This method must be called at least once after the
- * SRTCP cryptograhic context was set up.
+ * SRTP Cryptograhic context was set up.
*
- * This method clears the key data once it was processed by the encryptions'
- * set key functions.
- *
+ * @param index
+ * The 48 bit SRTP packet index. See the <code>guessIndex</code>
+ * method.
*/
void deriveSrtcpKeys();
/**
- * @brief Check for packet replay.
+ * Check for packet replay.
*
* The method check if a received packet is either to old or was already
* received.
@@ -210,7 +212,7 @@
bool checkReplay(uint32_t newSeqNumber);
/**
- * @brief Update the SRTCP packet index.
+ * Update the SRTP packet index.
*
* Call this method after all checks were successful. See chapter
* 3.3.1 in the RFC when to update the ROC and ROC processing.
@@ -218,77 +220,56 @@
* @param newSeqNumber
* The sequence number of the received RTCP packet in host order.
*/
- void update(uint32_t newSeqNumber);
+ void update( uint32_t newSeqNumber );
/**
- * @brief Get the length of the SRTCP authentication tag in bytes.
+ * Get the length of the SRTP authentication tag in bytes.
*
* @return the length of the authentication tag.
*/
- inline int32_t getTagLength() const { return tagLength; }
+ inline int32_t
+ getTagLength() const
+ {return tagLength;}
+
/**
- * @brief Get the length of the MKI in bytes.
+ * Get the length of the MKI in bytes.
*
* @return the length of the MKI.
*/
- inline int32_t getMkiLength() const { return mkiLength; }
+ inline int32_t
+ getMkiLength() const
+ {return mkiLength;}
/**
- * @brief Get the SSRC of this SRTCP Cryptograhic context.
+ * Get the SSRC of this SRTP Cryptograhic context.
*
* @return the SSRC.
*/
- inline uint32_t getSsrc() const { return ssrcCtx; }
+ inline uint32_t
+ getSsrc() const
+ {return ssrcCtx;}
/**
- * @brief Get the SRTCP index field of this SRTCP Cryptograhic context.
+ * Derive a new Crypto Context for use with a new SSRC
*
- * @return the SRTCP.
- */
- uint32_t getSrtcpIndex() const { return srtcpIndex; }
-
- /**
- * @brief Set the SRTCP index field of this SRTCP Cryptograhic context.
+ * This method returns a new Crypto Context initialized with the data
+ * of this crypto context. Replacing the SSRC, Roll-over-Counter, and
+ * the key derivation rate the application cab use this Crypto Context
+ * to encrypt / decrypt a new stream (Synchronization source) inside
+ * one RTP session.
*
- * @param index the new SRTCP index value.
- *
- */
- void setSrtcpIndex(uint32_t index) { srtcpIndex = index; }
-
- /**
- * @brief Set the start (base) number to compute the PRF labels.
- *
- * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
- * CryptoContextCtrl computes the labes as follows:
- *
- * - labelBase + 0 -> encryption label
- * - labelBase + 1 -> authentication label
- * - labelBase + 2 -> salting key label
- *
- * The CryptoContextCtrl constructor initializes CryptoContextCtrl#labelBase
- * with 3 to comply with RFC 3711 label values.
- *
- * Applications may set #labelBase to other values to use CryptoContextCtrl
- * for other purposes.
- */
- void setLabelbase(uint8_t base) { labelBase = base; }
-
- /**
- * @brief Derive a new Crypto Context for use with a new SSRC
- *
- * This method returns a new CryptoContextCtrl initialized with the data
- * of this crypto context. The application can use this CryptoContextCtrl
- * instance to encrypt / decrypt a new stream (Synchronization source) inside
- * one RTCP session.
- *
- * Before the application can use this crypto context it must call deriveSrtcpKeys().
+ * Before the application can use this crypto context it must call
+ * the <code>deriveSrtpKeys</code> method.
*
* @param ssrc
* The SSRC for this context
- *
+ * @param roc
+ * The Roll-Over-Counter for this context
+ * @param keyDerivRate
+ * The key derivation rate for this context
* @return
- * a new CryptoContextCtrl with all relevant data set.
+ * a new CryptoContext with all relevant data set.
*/
CryptoContextCtrl* newCryptoContextForSSRC(uint32_t ssrc);
@@ -323,8 +304,6 @@
int32_t akeyl;
int32_t skeyl;
int32_t tagLength;
- uint32_t srtcpIndex;
- uint8_t labelBase;
void* macCtx;
@@ -338,3 +317,11 @@
#endif
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/SrtpHandler.cpp b/jni/libzrtp/sources/srtp/SrtpHandler.cpp
deleted file mode 100644
index 621e25a..0000000
--- a/jni/libzrtp/sources/srtp/SrtpHandler.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/*
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
-
-#include <SrtpHandler.h>
-#include <CryptoContext.h>
-#include <CryptoContextCtrl.h>
-
-#define RTP_HEADER_LENGTH 12
-
-bool SrtpHandler::decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen)
-{
- int offset;
- uint16_t *pus;
- uint32_t *pui;
-
- /* Assume RTP header at the start of buffer. */
-
- if ((*buffer & 0xC0) != 0x80) { // check version bits
- return false;
- }
- if (length < RTP_HEADER_LENGTH)
- return false;
-
- /* Get some handy pointers */
- pus = (uint16_t*)buffer;
- pui = (uint32_t*)buffer;
-
- uint16_t tmp16 = pus[1]; // get seq number
- *seq = zrtpNtohs(tmp16); // and return in host oder
-
- uint32_t tmp32 = pui[2]; // get SSRC
- *ssrc = zrtpNtohl(tmp32); // and return in host order
-
- /* Payload is located right after header plus CSRC */
- int32_t numCC = buffer[0] & 0x0f; // lower 4 bits in first byte is num of contrib SSRC
- offset = RTP_HEADER_LENGTH + (numCC * sizeof(uint32_t));
-
- // Sanity check
- if (offset > length)
- return false;
-
- /* Adjust payload offset if RTP extension is used. */
- if ((*buffer & 0x10) == 0x10) { // packet contains RTP extension
- pus = (uint16_t*)(buffer + offset); // pus points to extension as 16bit pointer
- tmp16 = pus[1]; // the second 16 bit word is the length
- tmp16 = zrtpNtohs(tmp16); // to host order
- offset += (tmp16 + 1) * sizeof(uint32_t);
- }
- /* Sanity check */
- if (offset > length)
- return false;
-
- /* Set payload and payload length. */
- *payload = buffer + offset;
- *payloadlen = length - offset;
-
- return true;
-}
-
-bool SrtpHandler::protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
- uint8_t* payload = NULL;
- int32_t payloadlen = 0;
- uint16_t seqnum;
- uint32_t ssrc;
-
-
- if (pcc == NULL) {
- return false;
- }
- if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
- return false;
-
- /* Encrypt the packet */
- uint64_t index = ((uint64_t)pcc->getRoc() << 16) | (uint64_t)seqnum;
-
- pcc->srtpEncrypt(buffer, payload, payloadlen, index, ssrc);
-
- // NO MKI support yet - here we assume MKI is zero. To build in MKI
- // take MKI length into account when storing the authentication tag.
-
- /* Compute MAC and store at end of RTP packet data */
- if (pcc->getTagLength() > 0) {
- pcc->srtpAuthenticate(buffer, length, pcc->getRoc(), buffer+length);
- }
- *newLength = length + pcc->getTagLength();
-
- /* Update the ROC if necessary */
- if (seqnum == 0xFFFF ) {
- pcc->setRoc(pcc->getRoc() + 1);
- }
- return true;
-}
-
-int32_t SrtpHandler::unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
- uint8_t* payload = NULL;
- int32_t payloadlen = 0;
- uint16_t seqnum;
- uint32_t ssrc;
-
- if (pcc == NULL) {
- return 0;
- }
-
- if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
- return 0;
- /*
- * This is the setting of the packet data when we come to this point:
- *
- * length: complete length of received data
- * buffer: points to data as received from network
- * payloadlen: length of data excluding hdrSize and padding
- *
- * Because this is an SRTP packet we need to adjust some values here.
- * The SRTP MKI and authentication data is always at the end of a
- * packet. Thus compute the position of this data.
- */
- uint32_t srtpDataIndex = length - (pcc->getTagLength() + pcc->getMkiLength());
-
- // Compute new length
- length -= pcc->getTagLength() + pcc->getMkiLength();
- *newLength = length;
-
- // recompute payloadlen by subtracting SRTP data
- payloadlen -= pcc->getTagLength() + pcc->getMkiLength();
-
- // MKI is unused, so just skip it
- // const uint8* mki = buffer + srtpDataIndex;
- uint8_t* tag = buffer + srtpDataIndex + pcc->getMkiLength();
-
- /* Replay control */
- if (!pcc->checkReplay(seqnum)) {
- return -2;
- }
- /* Guess the index */
- uint64_t guessedIndex = pcc->guessIndex(seqnum);
-
- if (pcc->getTagLength() > 0) {
- uint32_t guessedRoc = guessedIndex >> 16;
- uint8_t mac[20];
-
- pcc->srtpAuthenticate(buffer, (uint32_t)length, guessedRoc, mac);
- if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
- return -1;
- }
- }
- /* Decrypt the content */
- pcc->srtpEncrypt(buffer, payload, payloadlen, guessedIndex, ssrc);
-
- /* Update the Crypto-context */
- pcc->update(seqnum);
-
- return 1;
-}
-
-
-bool SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-
- if (pcc == NULL) {
- return false;
- }
- /* Encrypt the packet */
- uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
- ssrc = zrtpNtohl(ssrc);
-
- uint32_t encIndex = pcc->getSrtcpIndex();
- pcc->srtcpEncrypt(buffer + 8, length - 8, encIndex, ssrc);
-
- encIndex |= 0x80000000; // set the E flag
-
- // Fill SRTCP index as last word
- uint32_t* ip = reinterpret_cast<uint32_t*>(buffer+length);
- *ip = zrtpHtonl(encIndex);
-
- // NO MKI support yet - here we assume MKI is zero. To build in MKI
- // take MKI length into account when storing the authentication tag.
-
- // Compute MAC and store in packet after the SRTCP index field
- pcc->srtcpAuthenticate(buffer, length, encIndex, buffer + length + sizeof(uint32_t));
-
- encIndex++;
- encIndex &= ~0x80000000; // clear the E-flag and modulo 2^31
- pcc->setSrtcpIndex(encIndex);
- *newLength = length + pcc->getTagLength() + sizeof(uint32_t);
-
- return true;
-}
-
-int32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-
- if (pcc == NULL) {
- return 0;
- }
-
- // Compute the total length of the payload
- int32_t payloadLen = length - (pcc->getTagLength() + pcc->getMkiLength() + 4);
- *newLength = payloadLen;
-
- // point to the SRTCP index field just after the real payload
- const uint32_t* index = reinterpret_cast<uint32_t*>(buffer + payloadLen);
-
- uint32_t encIndex = zrtpNtohl(*index);
- uint32_t remoteIndex = encIndex & ~0x80000000; // get index without Encryption flag
-
- if (!pcc->checkReplay(remoteIndex)) {
- return -2;
- }
-
- uint8_t mac[20];
-
- // Now get a pointer to the authentication tag field
- const uint8_t* tag = buffer + (length - pcc->getTagLength());
-
- // Authenticate includes the index, but not MKI and not (obviously) the tag itself
- pcc->srtcpAuthenticate(buffer, payloadLen, encIndex, mac);
- if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
- return -1;
- }
-
- uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
- ssrc = zrtpNtohl(ssrc);
-
- // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)
- if (encIndex & 0x80000000)
- pcc->srtcpEncrypt(buffer + 8, payloadLen - 8, remoteIndex, ssrc);
-
- // Update the Crypto-context
- pcc->update(remoteIndex);
-
- return 1;
-}
-
diff --git a/jni/libzrtp/sources/srtp/SrtpHandler.h b/jni/libzrtp/sources/srtp/SrtpHandler.h
deleted file mode 100644
index 1cc420b..0000000
--- a/jni/libzrtp/sources/srtp/SrtpHandler.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <stdint.h>
-
-class CryptoContext;
-class CryptoContextCtrl;
-
-/**
- * @brief SRTP and SRTCP protect and unprotect functions.
- *
- * The static methods take SRTP or SRTCP crypto contexts, a pointer uint8_t buffer
- * that must contain an RTP/SRTP packet and perform the actions necessary to protect
- * the RTP/RTCP packet or to unprotect the SRTP/SRTCP packet.
- *
- * The methods assume that the buffer contains all protocol relevant fields (SSRC,
- * sequence number etc.) in network order.
- *
- * When encrypting the buffer must be big enough to store additional data, usually
- * 4 - 14 bytes, depending on how the application configured the authentication parameters.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class SrtpHandler
-{
-public:
- /**
- * @brief Protect an RTP packet.
- *
- * @param pcc the SRTP CryptoContext instance
- *
- * @param buffer the RTP packet to protect
- *
- * @param length the length of the RTP packet data in bytes
- *
- * @param newLength the length of the resulting SRTP packet data in bytes
- *
- * @return @c true if protection was successful, @c false otherwise
- */
- static bool protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
- /**
- * @brief Unprotect a SRTP packet.
- *
- * @param pcc the SRTP CryptoContext instance
- *
- * @param buffer the SRTP packet to unprotect
- *
- * @param length the length of the SRTP packet data in bytes
- *
- * @param newLength the length of the resulting RTP packet data in bytes
- *
- * @return an integer value
- * - 1 - success
- * - -1 - SRTP authentication failed
- * - -2 - SRTP replay check failed
- */
- static int32_t unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
- /**
- * @brief Protect an RTCP packet.
- *
- * @param pcc the SRTCP CryptoContextCtrl instance
- *
- * @param buffer the RTCP packet to protect
- *
- * @param length the length of the RTCP packet data in bytes
- *
- * @param newLength the length of the resulting SRTCP packet data in bytes
- *
- * @return @c true if protection was successful, @c false otherwise
- */
- static bool protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
- /**
- * @brief Unprotect a SRTCP packet.
- *
- * @param pcc the SRTCP CryptoContextCtrl instance
- *
- * @param buffer the SRTCP packet to unprotect
- *
- * @param length the length of the SRTCP packet data in bytes
- *
- * @param newLength the length of the resulting RTCP packet data in bytes
- *
- * @return an integer value
- * - 0 - illegal packet (too short, not a valid RTP header byte), dismiss it
- * - 1 - success
- * - -1 - SRTCP authentication failed
- * - -2 - SRTCP replay check failed
- */
- static int32_t unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
-private:
- static bool decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen);
-
-};
\ No newline at end of file
diff --git a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp
deleted file mode 100644
index f92514d..0000000
--- a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#define MAKE_F8_TEST
-
-#include <stdlib.h>
-#include <crypto/SrtpSymCrypto.h>
-#include <cryptcommon/twofish.h>
-#include <cryptcommon/aesopt.h>
-#include <string.h>
-#include <stdio.h>
-#include <common/osSpecifics.h>
-
-SrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {
-}
-
-SrtpSymCrypto::SrtpSymCrypto( uint8_t* k, int32_t keyLength, int algo):
- key(NULL), algorithm(algo) {
-
- setNewKey(k, keyLength);
-}
-
-SrtpSymCrypto::~SrtpSymCrypto() {
- if (key != NULL) {
- if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
- AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
- memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));
- delete saAes;
- }
- else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
- memset(key, 0, sizeof(Twofish_key));
- delete[] (uint8_t*)key;
- }
- key = NULL;
- }
-}
-
-static int twoFishInit = 0;
-
-bool SrtpSymCrypto::setNewKey(const uint8_t* k, int32_t keyLength) {
- // release an existing key before setting a new one
- if (key != NULL) {
- if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
- AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
- memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));
- delete saAes;
- }
- else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
- memset(key, 0, sizeof(Twofish_key));
- delete[] (uint8_t*)key;
- }
- key = NULL;
- }
-
- if (!(keyLength == 16 || keyLength == 32)) {
- return false;
- }
- if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
- AESencrypt *saAes = new AESencrypt();
- if (keyLength == 16)
- saAes->key128(k);
- else
- saAes->key256(k);
- key = saAes;
- }
- else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
- if (!twoFishInit) {
- Twofish_initialise();
- twoFishInit = 1;
- }
- key = new uint8_t[sizeof(Twofish_key)];
- memset(key, 0, sizeof(Twofish_key));
- Twofish_prepare_key((Twofish_Byte*)k, keyLength, (Twofish_key*)key);
- }
- else
- return false;
-
- return true;
-}
-
-void SrtpSymCrypto::encrypt(const uint8_t* input, uint8_t* output) {
- if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
- AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
- saAes->encrypt(input, output);
- }
- else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
- Twofish_encrypt((Twofish_key*)key, (Twofish_Byte*)input,
- (Twofish_Byte*)output);
- }
-}
-
-void SrtpSymCrypto::get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv) {
- uint16_t ctr = 0;
- unsigned char temp[SRTP_BLOCK_SIZE];
-
- for(ctr = 0; ctr < length/SRTP_BLOCK_SIZE; ctr++) {
- //compute the cipher stream
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, &output[ctr*SRTP_BLOCK_SIZE]);
- }
- if ((length % SRTP_BLOCK_SIZE) > 0) {
- // Treat the last bytes:
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, temp);
- memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE );
- }
-}
-
-void SrtpSymCrypto::ctr_encrypt(const uint8_t* input, uint32_t input_length, uint8_t* output, uint8_t* iv) {
-
- if (key == NULL)
- return;
-
- uint16_t ctr = 0;
- unsigned char temp[SRTP_BLOCK_SIZE];
-
- int l = input_length/SRTP_BLOCK_SIZE;
- for (ctr = 0; ctr < l; ctr++ ) {
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, temp);
- for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {
- *output++ = temp[i] ^ *input++;
- }
-
- }
- l = input_length % SRTP_BLOCK_SIZE;
- if (l > 0) {
- // Treat the last bytes:
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, temp);
- for (int i = 0; i < l; i++ ) {
- *output++ = temp[i] ^ *input++;
- }
- }
-}
-
-void SrtpSymCrypto::ctr_encrypt( uint8_t* data, uint32_t data_length, uint8_t* iv ) {
-
- if (key == NULL)
- return;
-
- uint16_t ctr = 0;
- unsigned char temp[SRTP_BLOCK_SIZE];
-
- int l = data_length/SRTP_BLOCK_SIZE;
- for (ctr = 0; ctr < l; ctr++ ) {
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, temp);
- for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {
- *data++ ^= temp[i];
- }
-
- }
- l = data_length % SRTP_BLOCK_SIZE;
- if (l > 0) {
- // Treat the last bytes:
- iv[14] = (uint8_t)((ctr & 0xFF00) >> 8);
- iv[15] = (uint8_t)((ctr & 0x00FF));
-
- encrypt(iv, temp);
- for (int i = 0; i < l; i++ ) {
- *data++ ^= temp[i];
- }
- }
-}
-
-void SrtpSymCrypto::f8_encrypt(const uint8_t* data, uint32_t data_length,
- uint8_t* iv, SrtpSymCrypto* f8Cipher ) {
-
- f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);
-}
-
-#define MAX_KEYLEN 32
-
-void SrtpSymCrypto::f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen,
- uint8_t* salt, int32_t saltLen) {
-
- unsigned char *cp_in, *cp_in1, *cp_out;
-
- unsigned char maskedKey[MAX_KEYLEN];
- unsigned char saltMask[MAX_KEYLEN];
-
- if (keyLen > MAX_KEYLEN)
- return;
-
- if (saltLen > keyLen)
- return;
- /*
- * First copy the salt into the mask field, then fill with 0x55 to
- * get a full key.
- */
- memcpy(saltMask, salt, saltLen);
- memset(saltMask+saltLen, 0x55, keyLen-saltLen);
-
- /*
- * XOR the original key with the above created mask to
- * get the special key.
- */
- cp_out = maskedKey;
- cp_in = key;
- cp_in1 = saltMask;
- for (int i = 0; i < keyLen; i++) {
- *cp_out++ = *cp_in++ ^ *cp_in1++;
- }
- /*
- * Prepare the a new AES cipher with the special key to compute IV'
- */
- f8Cipher->setNewKey(maskedKey, keyLen);
-}
-
-void SrtpSymCrypto::f8_encrypt(const uint8_t* in, uint32_t in_length, uint8_t* out,
- uint8_t* iv, SrtpSymCrypto* f8Cipher ) {
-
-
- int offset = 0;
-
- unsigned char ivAccent[SRTP_BLOCK_SIZE];
- unsigned char S[SRTP_BLOCK_SIZE];
-
- F8_CIPHER_CTX f8ctx;
-
- if (key == NULL)
- return;
- /*
- * Get memory for the derived IV (IV')
- */
- f8ctx.ivAccent = ivAccent;
- /*
- * Use the derived IV encryption setup to encrypt the original IV to produce IV'.
- */
- f8Cipher->encrypt(iv, f8ctx.ivAccent);
-
- f8ctx.J = 0; // initialize the counter
- f8ctx.S = S; // get the key stream buffer
-
- memset(f8ctx.S, 0, SRTP_BLOCK_SIZE); // initial value for key stream
-
- while (in_length >= SRTP_BLOCK_SIZE) {
- processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);
- in_length -= SRTP_BLOCK_SIZE;
- offset += SRTP_BLOCK_SIZE;
- }
- if (in_length > 0) {
- processBlock(&f8ctx, in+offset, in_length, out+offset);
- }
-}
-
-int SrtpSymCrypto::processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t* in, int32_t length, uint8_t* out) {
-
- int i;
- const uint8_t *cp_in;
- uint8_t* cp_in1, *cp_out;
- uint32_t *ui32p;
-
- /*
- * XOR the previous key stream with IV'
- * ( S(-1) xor IV' )
- */
- cp_in = f8ctx->ivAccent;
- cp_out = f8ctx->S;
- for (i = 0; i < SRTP_BLOCK_SIZE; i++) {
- *cp_out++ ^= *cp_in++;
- }
- /*
- * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
- */
- ui32p = (uint32_t *)f8ctx->S;
- ui32p[3] ^= zrtpHtonl(f8ctx->J);
- f8ctx->J++;
- /*
- * Now compute the new key stream using AES encrypt
- */
- encrypt(f8ctx->S, f8ctx->S);
- /*
- * as the last step XOR the plain text with the key stream to produce
- * the ciphertext.
- */
- cp_out = out;
- cp_in = in;
- cp_in1 = f8ctx->S;
- for (i = 0; i < length; i++) {
- *cp_out++ = *cp_in++ ^ *cp_in1++;
- }
- return length;
-}
-
diff --git a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
index 09bdcab..1b596c8 100644
--- a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
+++ b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2008-2012 Werner Dittmann
+ Copyright (C) 2005, 2004, 2010, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -36,7 +36,7 @@
/**
* @file SrtpSymCrypto.h
- * @brief Class which implements SRTP cryptographic functions
+ * @brief Class which implements SRTP AES cryptographic functions
*
* @ingroup GNU_ZRTP
* @{
@@ -56,7 +56,7 @@
} F8_CIPHER_CTX;
/**
- * @brief Implments the SRTP encryption modes as defined in RFC3711
+ * Implments the SRTP encryption modes as defined in RFC3711
*
* The SRTP specification defines two encryption modes, AES-CTR
* (AES Counter mode) and AES-F8 mode. The AES-CTR is required,
@@ -70,43 +70,31 @@
* The implementation uses the openSSL library as its cryptographic
* backend.
*
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
class SrtpSymCrypto {
public:
- /**
- * @brief Constructor that does not initialize key data
- *
- * @param algo
- * The Encryption algorithm to use.Possible values are <code>
- * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
- * SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1
- * for CM (Counter mode) and 4.1.2 for F8 mode.
- */
SrtpSymCrypto(int algo = SrtpEncryptionAESCM);
/**
- * @brief Constructor that initializes key data
+ * Constructor that initializes key data
*
* @param key
* Pointer to key bytes.
* @param key_length
* Number of key bytes.
- * @param algo
- * The Encryption algorithm to use.Possible values are <code>
- * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
- * SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1
- * for CM (Counter mode) and 4.1.2 for F8 mode.
*/
SrtpSymCrypto(uint8_t* key, int32_t key_length, int algo = SrtpEncryptionAESCM);
~SrtpSymCrypto();
/**
- * @brief Encrypts the input to the output.
+ * Encrypts the inpout to the output.
*
* Encrypts one input block to one output block. Each block
- * is 16 bytes according to the encryption algorithms used.
+ * is 16 bytes according to the AES encryption algorithm used.
*
* @param input
* Pointer to input block, must be 16 bytes
@@ -117,7 +105,7 @@
void encrypt( const uint8_t* input, uint8_t* output );
/**
- * @brief Set new key
+ * Set new key
*
* @param key
* Pointer to key data, must have at least a size of keyLength
@@ -131,7 +119,7 @@
bool setNewKey(const uint8_t* key, int32_t keyLength);
/**
- * @brief Computes the cipher stream for AES CM mode.
+ * Computes the cipher stream for AES CM mode.
*
* @param output
* Pointer to a buffer that receives the cipher stream. Must be
@@ -148,9 +136,9 @@
void get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv);
/**
- * @brief Counter-mode encryption.
+ * Counter-mode encryption.
*
- * This method performs the CM encryption.
+ * This method performs the AES CM encryption.
*
* @param input
* Pointer to input buffer, must be <code>inputLen</code> bytes.
@@ -168,9 +156,9 @@
void ctr_encrypt(const uint8_t* input, uint32_t inputLen, uint8_t* output, uint8_t* iv );
/**
- * @brief Counter-mode encryption, in place.
+ * Counter-mode encryption, in place.
*
- * This method performs the CM encryption.
+ * This method performs the AES CM encryption.
*
* @param data
* Pointer to input and output block, must be <code>dataLen</code>
@@ -186,12 +174,12 @@
void ctr_encrypt(uint8_t* data, uint32_t data_length, uint8_t* iv );
/**
- * @brief Derive a cipher context to compute the IV'.
+ * Derive a AES context to compute the IV'.
*
* See chapter 4.1.2.1 in RFC 3711.
*
* @param f8Cipher
- * Pointer to the cipher context that will be used to encrypt IV to IV'
+ * Pointer to the AES context that will be used to encrypt IV to IV'
*
* @param key
* The master key
@@ -208,9 +196,10 @@
void f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen, uint8_t* salt, int32_t saltLen);
/**
- * @brief F8 mode encryption, in place.
+ * AES F8 mode encryption, in place.
*
- * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.
+ * This method performs the AES F8 encryption, see chapter 4.1.2
+ * in RFC 3711.
*
* @param data
* Pointer to input and output block, must be <code>dataLen</code>
@@ -229,9 +218,10 @@
void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* iv, SrtpSymCrypto* f8Cipher);
/**
- * @brief F8 mode encryption.
+ * AES F8 mode encryption.
*
- * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.
+ * This method performs the AES F8 encryption, see chapter 4.1.2
+ * in RFC 3711.
*
* @param data
* Pointer to input and output block, must be <code>dataLen</code>
@@ -262,13 +252,13 @@
int testF8();
#pragma GCC visibility pop
-/* Only SrtpSymCrypto functions defines the MAKE_F8_TEST */
+/* Only SrtpSymCrypto functions define the MAKE_F8_TEST */
#ifdef MAKE_F8_TEST
#include <cstring>
#include <iostream>
#include <cstdio>
-#include <common/osSpecifics.h>
+#include <arpa/inet.h>
using namespace std;
@@ -348,7 +338,7 @@
derivedIv[0] = 0;
// set ROC in network order into IV
- ui32p[3] = zrtpHtonl(ROC);
+ ui32p[3] = htonl(ROC);
int32_t pad = 0;
@@ -393,3 +383,11 @@
#endif
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/cryptcommon/brg_endian.h b/jni/libzrtp/sources/srtp/crypto/brg_endian.h
similarity index 66%
rename from jni/libzrtp/sources/cryptcommon/brg_endian.h
rename to jni/libzrtp/sources/srtp/crypto/brg_endian.h
index 82e48f0..c03c7c5 100644
--- a/jni/libzrtp/sources/cryptcommon/brg_endian.h
+++ b/jni/libzrtp/sources/srtp/crypto/brg_endian.h
@@ -1,39 +1,49 @@
/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
+ ---------------------------------------------------------------------------
+ Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
+ LICENSE TERMS
- source code distributions include the above copyright notice, this
- list of conditions and the following disclaimer;
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
- binary distributions include the above copyright notice, this list
- of conditions and the following disclaimer in their documentation.
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue 20/10/2006
*/
-#ifndef _BRG_ENDIAN_H
-#define _BRG_ENDIAN_H
+#ifndef BRG_ENDIAN_H
+#define BRG_ENDIAN_H
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
/* Include files where endian defines and byteswap functions may reside */
-#if defined( __sun )
-# include <sys/isa_defs.h>
-#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
+#if defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
# include <sys/endian.h>
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
# include <machine/endian.h>
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
-# if !defined( __MINGW32__ ) && !defined( _AIX )
+# if !defined( __MINGW32__ ) && !defined(AVR)
# include <endian.h>
# if !defined( __BEOS__ )
# include <byteswap.h>
@@ -101,7 +111,7 @@
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
defined( vax ) || defined( vms ) || defined( VMS ) || \
- defined( __VMS ) || defined( _M_X64 )
+ defined( __VMS ) || defined( _M_X64 ) || defined( AVR )
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
@@ -110,7 +120,7 @@
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
- defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
+ defined( THINK_C ) || defined( __VMCMS__ )
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
@@ -120,7 +130,19 @@
#else
# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
#endif
-
#endif
+/* special handler for IA64, which may be either endianness (?) */
+/* here we assume little-endian, but this may need to be changed */
+#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+# define PLATFORM_MUST_ALIGN (1)
+#ifndef PLATFORM_BYTE_ORDER
+# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
#endif
+#endif
+
+#ifndef PLATFORM_MUST_ALIGN
+# define PLATFORM_MUST_ALIGN (0)
+#endif
+
+#endif /* ifndef BRG_ENDIAN_H */
diff --git a/jni/libzrtp/sources/srtp/crypto/brg_types.h b/jni/libzrtp/sources/srtp/crypto/brg_types.h
new file mode 100644
index 0000000..6db737d
--- /dev/null
+++ b/jni/libzrtp/sources/srtp/crypto/brg_types.h
@@ -0,0 +1,188 @@
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue 09/09/2006
+
+ The unsigned integer types defined here are of the form uint_<nn>t where
+ <nn> is the length of the type; for example, the unsigned 32-bit type is
+ 'uint_32t'. These are NOT the same as the 'C99 integer types' that are
+ defined in the inttypes.h and stdint.h headers since attempts to use these
+ types have shown that support for them is still highly variable. However,
+ since the latter are of the form uint<nn>_t, a regular expression search
+ and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
+ can be used to convert the types used here to the C99 standard types.
+*/
+
+#ifndef BRG_TYPES_H
+#define BRG_TYPES_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <limits.h>
+
+#ifndef BRG_UI8
+# define BRG_UI8
+# if UCHAR_MAX == 255u
+ typedef unsigned char uint_8t;
+# else
+# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h
+# endif
+#endif
+
+#ifndef BRG_UI16
+# define BRG_UI16
+# if USHRT_MAX == 65535u
+ typedef unsigned short uint_16t;
+# else
+# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h
+# endif
+#endif
+
+#ifndef BRG_UI32
+# define BRG_UI32
+# if UINT_MAX == 4294967295u
+# define li_32(h) 0x##h##u
+ typedef unsigned int uint_32t;
+# elif ULONG_MAX == 4294967295u
+# define li_32(h) 0x##h##ul
+ typedef unsigned long uint_32t;
+# elif defined( _CRAY )
+# error This code needs 32-bit data types, which Cray machines do not provide
+# else
+# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h
+# endif
+#endif
+
+#ifndef BRG_UI64
+# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
+# define BRG_UI64
+# define li_64(h) 0x##h##ui64
+ typedef unsigned __int64 uint_64t;
+# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
+# define BRG_UI64
+# define li_64(h) 0x##h##ui64
+ typedef unsigned __int64 uint_64t;
+# elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful
+# define BRG_UI64
+# define li_64(h) 0x##h##ull
+ typedef unsigned long long uint_64t;
+# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
+# if UINT_MAX == 18446744073709551615u
+# define BRG_UI64
+# define li_64(h) 0x##h##u
+ typedef unsigned int uint_64t;
+# endif
+# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
+# if ULONG_MAX == 18446744073709551615ul
+# define BRG_UI64
+# define li_64(h) 0x##h##ul
+ typedef unsigned long uint_64t;
+# endif
+# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
+# if ULLONG_MAX == 18446744073709551615ull
+# define BRG_UI64
+# define li_64(h) 0x##h##ull
+ typedef unsigned long long uint_64t;
+# endif
+# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
+# if ULONG_LONG_MAX == 18446744073709551615ull
+# define BRG_UI64
+# define li_64(h) 0x##h##ull
+ typedef unsigned long long uint_64t;
+# endif
+# elif defined(__GNUC__) /* DLW: avoid mingw problem with -ansi */
+# define BRG_UI64
+# define li_64(h) 0x##h##ull
+ typedef unsigned long long uint_64t;
+# endif
+#endif
+
+#if defined( NEED_UINT_64T ) && !defined( BRG_UI64 )
+# error Please define uint_64t as an unsigned 64 bit type in brg_types.h
+#endif
+
+#ifndef RETURN_VALUES
+# define RETURN_VALUES
+# if defined( DLL_EXPORT )
+# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
+# define VOID_RETURN __declspec( dllexport ) void __stdcall
+# define INT_RETURN __declspec( dllexport ) int __stdcall
+# elif defined( __GNUC__ )
+# define VOID_RETURN __declspec( __dllexport__ ) void
+# define INT_RETURN __declspec( __dllexport__ ) int
+# else
+# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
+# endif
+# elif defined( DLL_IMPORT )
+# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
+# define VOID_RETURN __declspec( dllimport ) void __stdcall
+# define INT_RETURN __declspec( dllimport ) int __stdcall
+# elif defined( __GNUC__ )
+# define VOID_RETURN __declspec( __dllimport__ ) void
+# define INT_RETURN __declspec( __dllimport__ ) int
+# else
+# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
+# endif
+# elif defined( __WATCOMC__ )
+# define VOID_RETURN void __cdecl
+# define INT_RETURN int __cdecl
+# else
+# define VOID_RETURN void
+# define INT_RETURN int
+# endif
+#endif
+
+/* These defines are used to declare buffers in a way that allows
+ faster operations on longer variables to be used. In all these
+ defines 'size' must be a power of 2 and >= 8
+
+ dec_unit_type(size,x) declares a variable 'x' of length
+ 'size' bits
+
+ dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize'
+ bytes defined as an array of variables
+ each of 'size' bits (bsize must be a
+ multiple of size / 8)
+
+ ptr_cast(x,size) casts a pointer to a pointer to a
+ varaiable of length 'size' bits
+*/
+
+#define ui_type(size) uint_##size##t
+#define dec_unit_type(size,x) typedef ui_type(size) x
+#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]
+#define ptr_cast(x,size) ((ui_type(size)*)(x))
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
index 1c743d2..78fad51 100644
--- a/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2013 Werner Dittmann
+ Copyright (C) 2006-2007 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -17,7 +17,7 @@
#include <stdio.h>
-#include <string.h>
+#include <malloc.h>
#include <pthread.h>
#include <errno.h>
#include <gcrypt.h>
diff --git a/jni/libzrtp/sources/srtp/crypto/hmac.cpp b/jni/libzrtp/sources/srtp/crypto/hmac.cpp
deleted file mode 100644
index 38028a3..0000000
--- a/jni/libzrtp/sources/srtp/crypto/hmac.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "crypto/sha1.h"
-#include "crypto/hmac.h"
-
-typedef struct _hmacSha1Context {
- sha1_ctx ctx;
- sha1_ctx innerCtx;
- sha1_ctx outerCtx;
-} hmacSha1Context;
-
-static int32_t hmacSha1Init(hmacSha1Context *ctx, const uint8_t *key, uint32_t kLength)
-{
- int32_t i;
- uint8_t localPad[SHA1_BLOCK_SIZE] = {0};
- uint8_t localKey[SHA1_BLOCK_SIZE] = {0};
-
- if (key == NULL)
- return 0;
-
- memset(ctx, 0, sizeof(hmacSha1Context));
-
- /* check key length and reduce it if necessary */
- if (kLength > SHA1_BLOCK_SIZE) {
- sha1_begin(&ctx->ctx);
- sha1_hash(key, kLength, &ctx->ctx);
- sha1_end(localKey, &ctx->ctx);
- }
- else {
- memcpy(localKey, key, kLength);
- }
- /* prepare inner hash and hold the context */
- for (i = 0; i < SHA1_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x36;
-
- sha1_begin(&ctx->innerCtx);
- sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->innerCtx);
-
- /* prepare outer hash and hold the context */
- for (i = 0; i < SHA1_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x5c;
-
- sha1_begin(&ctx->outerCtx);
- sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->outerCtx);
-
- /* copy prepared inner hash to work hash - ready to process data */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));
-
- memset(localKey, 0, sizeof(localKey));
-
- return 1;
-}
-
-static void hmacSha1Reset(hmacSha1Context *ctx)
-{
- /* copy prepared inner hash to work hash context */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));
-}
-
-static void hmacSha1Update(hmacSha1Context *ctx, const uint8_t *data, uint32_t dLength)
-{
- /* hash new data to work hash context */
- sha1_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha1Final(hmacSha1Context *ctx, uint8_t *mac)
-{
- uint8_t tmpDigest[SHA1_DIGEST_SIZE];
-
- /* finalize work hash context */
- sha1_end(tmpDigest, &ctx->ctx);
-
- /* copy prepared outer hash to work hash */
- memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha1_ctx));
-
- /* hash inner digest to work (outer) hash context */
- sha1_hash(tmpDigest, SHA1_DIGEST_SIZE, &ctx->ctx);
-
- /* finalize work hash context to get the hmac*/
- sha1_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha1(uint8_t *key, int32_t keyLength, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
- hmacSha1Context ctx;
-
- hmacSha1Init(&ctx, key, keyLength);
- hmacSha1Update(&ctx, data, dataLength);
- hmacSha1Final(&ctx, mac);
- *macLength = SHA1_BLOCK_SIZE;
-}
-
-void hmac_sha1( uint8_t* key, int32_t keyLength, const uint8_t* dataChunks[], uint32_t dataChunckLength[],
- uint8_t* mac, int32_t* macLength )
-{
- hmacSha1Context ctx;
-
- hmacSha1Init(&ctx, key, keyLength);
-
- while (*dataChunks) {
- hmacSha1Update(&ctx, *dataChunks, *dataChunckLength);
- dataChunks ++;
- dataChunckLength ++;
- }
- hmacSha1Final(&ctx, mac);
- *macLength = SHA1_BLOCK_SIZE;
-}
-
-void* createSha1HmacContext(uint8_t* key, int32_t keyLength)
-{
- hmacSha1Context *ctx = reinterpret_cast<hmacSha1Context*>(malloc(sizeof(hmacSha1Context)));
-
- hmacSha1Init(ctx, key, keyLength);
- return ctx;
-}
-
-void hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
- uint8_t* mac, int32_t* macLength)
-{
- hmacSha1Context *pctx = (hmacSha1Context*)ctx;
-
- hmacSha1Reset(pctx);
- hmacSha1Update(pctx, data, dataLength);
- hmacSha1Final(pctx, mac);
- *macLength = SHA1_BLOCK_SIZE;
-}
-
-void hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
- uint8_t* mac, int32_t* macLength )
-{
- hmacSha1Context *pctx = (hmacSha1Context*)ctx;
-
- hmacSha1Reset(pctx);
- while (*data) {
- hmacSha1Update(pctx, *data, *dataLength);
- data++;
- dataLength++;
- }
- hmacSha1Final(pctx, mac);
- *macLength = SHA1_BLOCK_SIZE;
-}
-
-void freeSha1HmacContext(void* ctx)
-{
- if (ctx) {
- memset(ctx, 0, sizeof(hmacSha1Context));
- free(ctx);
- }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/srtp/crypto/hmac.h b/jni/libzrtp/sources/srtp/crypto/hmac.h
index 6d99f92..4abfa8f 100644
--- a/jni/libzrtp/sources/srtp/crypto/hmac.h
+++ b/jni/libzrtp/sources/srtp/crypto/hmac.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2005, 2004, 2010 Erik Eliasson, Johan Bilien, Werner Dittmann
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -32,6 +32,8 @@
/**
* Functions to compute SHA1 HAMAC.
*
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
* @author Werner Dittmann
*/
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.cpp b/jni/libzrtp/sources/srtp/crypto/macSkein.cpp
similarity index 93%
rename from jni/libzrtp/sources/cryptcommon/macSkein.cpp
rename to jni/libzrtp/sources/srtp/crypto/macSkein.cpp
index 9da946f..ba4c260 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/macSkein.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2010-2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -15,7 +15,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
#include <stdlib.h>
void macSkein(uint8_t* key, int32_t key_length,
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.h b/jni/libzrtp/sources/srtp/crypto/macSkein.h
similarity index 96%
rename from jni/libzrtp/sources/cryptcommon/macSkein.h
rename to jni/libzrtp/sources/srtp/crypto/macSkein.h
index ce5d380..71c2ad9 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.h
+++ b/jni/libzrtp/sources/srtp/crypto/macSkein.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2010-2013 Werner Dittmann
+ Copyright (C) 2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
+ it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -19,7 +19,7 @@
#ifndef MAC_SKEIN_H
#define MAC_SKEIN_H
-#include <cryptcommon/skeinApi.h>
+#include <crypto/skeinApi.h>
/**
* @file macSkein.h
* @brief Function that provide Skein MAC support
diff --git a/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp b/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
index 00d4476..3d6747d 100644
--- a/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Werner Dittmann
+ Copyright (C) 2005, 2004, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,8 @@
*/
/**
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
@@ -38,10 +40,10 @@
#include <stdlib.h>
#include <openssl/aes.h> // the include of openSSL
#include <crypto/SrtpSymCrypto.h>
-#include <cryptcommon/twofish.h>
+#include <crypto/twofish.h>
#include <string.h>
#include <stdio.h>
-#include <common/osSpecifics.h>
+#include <arpa/inet.h>
SrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {
}
@@ -294,7 +296,7 @@
* Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
*/
ui32p = (uint32_t *)f8ctx->S;
- ui32p[3] ^= zrtpHtonl(f8ctx->J);
+ ui32p[3] ^= htonl(f8ctx->J);
f8ctx->J++;
/*
* Now compute the new key stream using AES encrypt
@@ -313,3 +315,12 @@
return length;
}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp b/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
index cfe73c3..88d33a1 100644
--- a/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2005, 2004, 2010, Erik Eliasson, Johan Bilien, Werner Dittmann
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -30,7 +30,9 @@
*/
/*
- * Authors: Werner Dittmann
+ * Authors: Erik Eliasson <eliasson@it.kth.se>
+ * Johan Bilien <jobi@via.ecp.fr>
+ * Werner Dittmann
*/
#include <stdint.h>
@@ -65,7 +67,7 @@
void* createSha1HmacContext(uint8_t* key, int32_t key_length)
{
HMAC_CTX* ctx = (HMAC_CTX*)malloc(sizeof(HMAC_CTX));
-
+
HMAC_CTX_init(ctx);
HMAC_Init_ex(ctx, key, key_length, EVP_sha1(), NULL);
return ctx;
diff --git a/jni/libzrtp/sources/srtp/crypto/sha1.c b/jni/libzrtp/sources/srtp/crypto/sha1.c
deleted file mode 100644
index 31cee60..0000000
--- a/jni/libzrtp/sources/srtp/crypto/sha1.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-
- This is a byte oriented version of SHA1 that operates on arrays of bytes
- stored in memory.
-*/
-
-#include <string.h> /* for memcpy() etc. */
-
-#include "sha1.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#if 0 && defined(_MSC_VER)
-#define rotl32 _lrotl
-#define rotr32 _lrotr
-#else
-#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
-#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
-#endif
-
-#if !defined(bswap_32)
-#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
-#endif
-
-#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
-#define SWAP_BYTES
-#else
-#undef SWAP_BYTES
-#endif
-
-#if defined(SWAP_BYTES)
-#define bsw_32(p,n) \
- { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
-#else
-#define bsw_32(p,n)
-#endif
-
-#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
-
-#if 0
-
-#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
-#define parity(x,y,z) ((x) ^ (y) ^ (z))
-#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-#else /* Discovered by Rich Schroeppel and Colin Plumb */
-
-#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define parity(x,y,z) ((x) ^ (y) ^ (z))
-#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
-
-#endif
-
-/* Compile 64 bytes of hash data into SHA1 context. Note */
-/* that this routine assumes that the byte order in the */
-/* ctx->wbuf[] at this point is in such an order that low */
-/* address bytes in the ORIGINAL byte stream will go in */
-/* this buffer to the high end of 32-bit words on BOTH big */
-/* and little endian systems */
-
-#ifdef ARRAY
-#define q(v,n) v[n]
-#else
-#define q(v,n) v##n
-#endif
-
-#define one_cycle(v,a,b,c,d,e,f,k,h) \
- q(v,e) += rotr32(q(v,a),27) + \
- f(q(v,b),q(v,c),q(v,d)) + k + h; \
- q(v,b) = rotr32(q(v,b), 2)
-
-#define five_cycle(v,f,k,i) \
- one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \
- one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \
- one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \
- one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \
- one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
-
-VOID_RETURN sha1_compile(sha1_ctx ctx[1])
-{ uint_32t *w = ctx->wbuf;
-
-#ifdef ARRAY
- uint_32t v[5];
- memcpy(v, ctx->hash, 5 * sizeof(uint_32t));
-#else
- uint_32t v0, v1, v2, v3, v4;
- v0 = ctx->hash[0]; v1 = ctx->hash[1];
- v2 = ctx->hash[2]; v3 = ctx->hash[3];
- v4 = ctx->hash[4];
-#endif
-
-#define hf(i) w[i]
-
- five_cycle(v, ch, 0x5a827999, 0);
- five_cycle(v, ch, 0x5a827999, 5);
- five_cycle(v, ch, 0x5a827999, 10);
- one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
-
-#undef hf
-#define hf(i) (w[(i) & 15] = rotl32( \
- w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
- ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
-
- one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
- one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
- one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
- one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
-
- five_cycle(v, parity, 0x6ed9eba1, 20);
- five_cycle(v, parity, 0x6ed9eba1, 25);
- five_cycle(v, parity, 0x6ed9eba1, 30);
- five_cycle(v, parity, 0x6ed9eba1, 35);
-
- five_cycle(v, maj, 0x8f1bbcdc, 40);
- five_cycle(v, maj, 0x8f1bbcdc, 45);
- five_cycle(v, maj, 0x8f1bbcdc, 50);
- five_cycle(v, maj, 0x8f1bbcdc, 55);
-
- five_cycle(v, parity, 0xca62c1d6, 60);
- five_cycle(v, parity, 0xca62c1d6, 65);
- five_cycle(v, parity, 0xca62c1d6, 70);
- five_cycle(v, parity, 0xca62c1d6, 75);
-
-#ifdef ARRAY
- ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
- ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
- ctx->hash[4] += v[4];
-#else
- ctx->hash[0] += v0; ctx->hash[1] += v1;
- ctx->hash[2] += v2; ctx->hash[3] += v3;
- ctx->hash[4] += v4;
-#endif
-}
-
-VOID_RETURN sha1_begin(sha1_ctx ctx[1])
-{
- ctx->count[0] = ctx->count[1] = 0;
- ctx->hash[0] = 0x67452301;
- ctx->hash[1] = 0xefcdab89;
- ctx->hash[2] = 0x98badcfe;
- ctx->hash[3] = 0x10325476;
- ctx->hash[4] = 0xc3d2e1f0;
-}
-
-/* SHA1 hash data in an array of bytes into hash buffer and */
-/* call the hash_compile function as required. */
-
-VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
-{
- uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK),
- space = SHA1_BLOCK_SIZE - pos;
- const unsigned char *sp = data;
-
- if((ctx->count[0] += len) < len)
- ++(ctx->count[1]);
-
- while(len >= space) /* tranfer whole blocks if possible */
- {
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
- sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
- bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);
- sha1_compile(ctx);
- }
-
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA1 final padding and digest calculation */
-
-VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
-{ uint_32t i = (uint_32t)(ctx->count[0] & SHA1_MASK);
-
- /* put bytes in the buffer in an order in which references to */
- /* 32-bit words will put bytes with lower addresses into the */
- /* top of 32 bit words on BOTH big and little endian machines */
- bsw_32(ctx->wbuf, (i + 3) >> 2);
-
- /* we now need to mask valid bytes and add the padding which is */
- /* a single 1 bit and as many zero bits as necessary. Note that */
- /* we can always add the first padding byte here because the */
- /* buffer always has at least one empty slot */
- ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
- ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
-
- /* we need 9 or more empty positions, one for the padding byte */
- /* (above) and eight for the length count. If there is not */
- /* enough space, pad and empty the buffer */
- if(i > SHA1_BLOCK_SIZE - 9)
- {
- if(i < 60) ctx->wbuf[15] = 0;
- sha1_compile(ctx);
- i = 0;
- }
- else /* compute a word index for the empty buffer positions */
- i = (i >> 2) + 1;
-
- while(i < 14) /* and zero pad all but last two positions */
- ctx->wbuf[i++] = 0;
-
- /* the following 32-bit length fields are assembled in the */
- /* wrong byte order on little endian machines but this is */
- /* corrected later since they are only ever used as 32-bit */
- /* word values. */
- ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
- ctx->wbuf[15] = ctx->count[0] << 3;
- sha1_compile(ctx);
-
- /* extract the hash value as bytes in case the hash buffer is */
- /* misaligned for 32-bit words */
- for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
- hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
-}
-
-VOID_RETURN bg_sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
-{ sha1_ctx cx[1];
-
- sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/srtp/crypto/sha1.h b/jni/libzrtp/sources/srtp/crypto/sha1.h
deleted file mode 100644
index 79fb680..0000000
--- a/jni/libzrtp/sources/srtp/crypto/sha1.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-*/
-
-#ifndef _SHA1_H
-#define _SHA1_H
-
-#include <stdlib.h>
-#include <cryptcommon/brg_types.h>
-
-#define SHA1_BLOCK_SIZE 64
-#define SHA1_DIGEST_SIZE 20
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* type to hold the SHA256 context */
-
-typedef struct
-{ uint_32t count[2];
- uint_32t hash[5];
- uint_32t wbuf[16];
-} sha1_ctx;
-
-/* Note that these prototypes are the same for both bit and */
-/* byte oriented implementations. However the length fields */
-/* are in bytes or bits as appropriate for the version used */
-/* and bit sequences are input as arrays of bytes in which */
-/* bit sequences run from the most to the least significant */
-/* end of each byte */
-
-VOID_RETURN sha1_compile(sha1_ctx ctx[1]);
-
-VOID_RETURN sha1_begin(sha1_ctx ctx[1]);
-VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);
-VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
-VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/skein.c b/jni/libzrtp/sources/srtp/crypto/skein.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein.c
rename to jni/libzrtp/sources/srtp/crypto/skein.c
index 9c6451d..5935a2a 100644
--- a/jni/libzrtp/sources/cryptcommon/skein.c
+++ b/jni/libzrtp/sources/srtp/crypto/skein.c
@@ -11,8 +11,8 @@
#define SKEIN_PORT_CODE /* instantiate any code in skein_port.h */
#include <string.h> /* get the memcpy/memset functions */
-#include <cryptcommon/skein.h> /* get the Skein API definitions */
-#include <cryptcommon/skein_iv.h> /* get precomputed IVs */
+#include <crypto/skein.h> /* get the Skein API definitions */
+#include <crypto/skein_iv.h> /* get precomputed IVs */
/*****************************************************************/
/* External function to process blkCnt (nonzero) full block(s) of data. */
diff --git a/jni/libzrtp/sources/cryptcommon/skein.h b/jni/libzrtp/sources/srtp/crypto/skein.h
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein.h
rename to jni/libzrtp/sources/srtp/crypto/skein.h
index 135aeb3..345a112 100644
--- a/jni/libzrtp/sources/cryptcommon/skein.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein.h
@@ -33,7 +33,7 @@
#endif
#include <stddef.h> /* get size_t definition */
-#include <cryptcommon/skein_port.h> /* get platform-specific definitions */
+#include <crypto/skein_port.h> /* get platform-specific definitions */
enum
{
diff --git a/jni/libzrtp/sources/cryptcommon/skeinApi.c b/jni/libzrtp/sources/srtp/crypto/skeinApi.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skeinApi.c
rename to jni/libzrtp/sources/srtp/crypto/skeinApi.c
index f403b53..84f0120 100644
--- a/jni/libzrtp/sources/cryptcommon/skeinApi.c
+++ b/jni/libzrtp/sources/srtp/crypto/skeinApi.c
@@ -25,7 +25,7 @@
*/
#define SKEIN_ERR_CHECK 1
-#include <cryptcommon/skeinApi.h>
+#include <crypto/skeinApi.h>
#include <string.h>
#include <stdio.h>
diff --git a/jni/libzrtp/sources/cryptcommon/skeinApi.h b/jni/libzrtp/sources/srtp/crypto/skeinApi.h
similarity index 94%
rename from jni/libzrtp/sources/cryptcommon/skeinApi.h
rename to jni/libzrtp/sources/srtp/crypto/skeinApi.h
index 4d25ba5..2f25073 100644
--- a/jni/libzrtp/sources/cryptcommon/skeinApi.h
+++ b/jni/libzrtp/sources/srtp/crypto/skeinApi.h
@@ -32,12 +32,12 @@
* @brief A Skein API and its functions.
* @{
*
- * This API and the functions that implement this API simplify usage
+ * This API and the functions that implement this API simplify the usage
* of Skein. The design and the way to use the functions follow the openSSL
* design but at the same time take care of some Skein specific behaviour
* and possibilities.
*
- * The functions enable applications to create normal Skein hashes and
+ * The functions enable applications to create a normal Skein hashes and
* message authentication codes (MAC).
*
* Using these functions is simple and straight forward:
@@ -52,9 +52,9 @@
* // prepare context, here for a Skein with a state size of 512 bits.
* skeinCtxPrepare(&ctx, Skein512);
*
- * // Initialize the context to set the requested hash length in bits:
- * // request an output hash size of 31 bits (Skein supports variable
- * // output sizes, even very strange sizes)
+ * // Initialize the context to set the requested hash length in bits
+ * // here request a output hash size of 31 bits (Skein supports variable
+ * // output sizes even very strange sizes)
* skeinInit(&ctx, 31);
*
* // Now update Skein with any number of message bits. A function that
@@ -71,14 +71,14 @@
* An application may use @c skeinReset to reset a Skein context and use
* it for creation of another hash with the same Skein state size and output
* bit length. In this case the API implementation restores some internal
- * state data and saves a full Skein initialization round.
+ * internal state data and saves a full Skein initialization round.
*
* To create a MAC the application just uses @c skeinMacInit instead of
- * @c skeinInit. All other function calls remain the same.
+ * @c skeinInit. All other functions calls remain the same.
*
*/
-#include <cryptcommon/skein.h>
+#include <crypto/skein.h>
#ifdef _MSC_VER
typedef signed __int8 int8_t;
diff --git a/jni/libzrtp/sources/cryptcommon/skein_block.c b/jni/libzrtp/sources/srtp/crypto/skein_block.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein_block.c
rename to jni/libzrtp/sources/srtp/crypto/skein_block.c
index d1c5ece..fbf37e7 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_block.c
+++ b/jni/libzrtp/sources/srtp/crypto/skein_block.c
@@ -15,7 +15,7 @@
************************************************************************/
#include <string.h>
-#include <cryptcommon/skein.h>
+#include <crypto/skein.h>
#ifndef SKEIN_USE_ASM
#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */
diff --git a/jni/libzrtp/sources/cryptcommon/skein_iv.h b/jni/libzrtp/sources/srtp/crypto/skein_iv.h
similarity index 98%
rename from jni/libzrtp/sources/cryptcommon/skein_iv.h
rename to jni/libzrtp/sources/srtp/crypto/skein_iv.h
index 22f591e..0c62fac 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_iv.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein_iv.h
@@ -1,7 +1,7 @@
#ifndef _SKEIN_IV_H_
#define _SKEIN_IV_H_
-#include <cryptcommon/skein.h> /* get Skein macros and types */
+#include <crypto/skein.h> /* get Skein macros and types */
/*
***************** Pre-computed Skein IVs *******************
diff --git a/jni/libzrtp/sources/cryptcommon/skein_port.h b/jni/libzrtp/sources/srtp/crypto/skein_port.h
similarity index 95%
rename from jni/libzrtp/sources/cryptcommon/skein_port.h
rename to jni/libzrtp/sources/srtp/crypto/skein_port.h
index 10cc08c..256e9d5 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_port.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein_port.h
@@ -15,7 +15,7 @@
**
********************************************************************/
-#include <cryptcommon/brg_types.h> /* get integer type definitions */
+#include <crypto/brg_types.h> /* get integer type definitions */
/*r3gis3r : android already has that defined in types */
#ifndef ANDROID
@@ -49,7 +49,7 @@
*/
#ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
-#include <cryptcommon/brg_endian.h> /* get endianness selection */
+#include <crypto/brg_endian.h> /* get endianness selection */
#if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN
/* here for big-endian CPUs */
#define SKEIN_NEED_SWAP (1)
diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
deleted file mode 100644
index abe0a81..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-// #define UNIT_TEST
-
-#include <string>
-#include <time.h>
-#include <stdlib.h>
-
-#include <libzrtpcpp/ZIDCacheDb.h>
-
-
-static ZIDCacheDb* instance;
-
-/**
- * A poor man's factory.
- *
- * The build process must not allow to implementation classes linked
- * into the same library.
- */
-
-ZIDCache* getZidCacheInstance() {
-
- if (instance == NULL) {
- instance = new ZIDCacheDb();
- }
- return instance;
-}
-
-
-ZIDCacheDb::~ZIDCacheDb() {
- close();
-}
-
-int ZIDCacheDb::open(char* name) {
-
- // check for an already active ZID file
- if (zidFile != NULL) {
- return 0;
- }
- if (cacheOps.openCache(name, &zidFile, errorBuffer) == 0)
- cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);
- else {
- cacheOps.closeCache(zidFile);
- zidFile = NULL;
- }
-
- return ((zidFile == NULL) ? -1 : 1);
-}
-
-void ZIDCacheDb::close() {
-
- if (zidFile != NULL) {
- cacheOps.closeCache(zidFile);
- zidFile = NULL;
- }
-}
-
-ZIDRecord *ZIDCacheDb::getRecord(unsigned char *zid) {
- ZIDRecordDb *zidRecord = new ZIDRecordDb();
-
- cacheOps.readRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);
-
- zidRecord->setZid(zid);
-
- // We need to create a new ZID record.
- if (!zidRecord->isValid()) {
- zidRecord->setValid();
- zidRecord->getRecordData()->secureSince = (int64_t)time(NULL);
- cacheOps.insertRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);
- }
- return zidRecord;
-}
-
-unsigned int ZIDCacheDb::saveRecord(ZIDRecord *zidRec) {
- ZIDRecordDb *zidRecord = reinterpret_cast<ZIDRecordDb *>(zidRec);
-
- cacheOps.updateRemoteZidRecord(zidFile, zidRecord->getIdentifier(), associatedZid, zidRecord->getRecordData(), errorBuffer);
- return 1;
-}
-
-int32_t ZIDCacheDb::getPeerName(const uint8_t *peerZid, std::string *name) {
- zidNameRecord_t nameRec;
- char buffer[201] = {'\0'};
-
- nameRec.name = buffer;
- nameRec.nameLength = 200;
- cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
- if ((nameRec.flags & Valid) != Valid) {
- return 0;
- }
- name->assign(buffer);
- return name->length();
-}
-
-void ZIDCacheDb::putPeerName(const uint8_t *peerZid, const std::string name) {
- zidNameRecord_t nameRec;
- char buffer[201] = {'\0'};
-
- nameRec.name = buffer;
- nameRec.nameLength = 200;
- cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-
- nameRec.name = (char*)name.c_str();
- nameRec.nameLength = name.length();
- nameRec.nameLength = nameRec.nameLength > 200 ? 200 : nameRec.nameLength;
- if ((nameRec.flags & Valid) != Valid) {
- nameRec.flags = Valid;
- cacheOps.insertZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
- }
- else
- cacheOps.updateZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-
- return;
-}
-
-void ZIDCacheDb::cleanup() {
- cacheOps.cleanCache(zidFile, errorBuffer);
- cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
deleted file mode 100644
index 5975fc2..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-// #define UNIT_TEST
-
-#include <string>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <crypto/zrtpDH.h>
-
-#include <libzrtpcpp/ZIDCacheFile.h>
-
-
-static ZIDCacheFile* instance;
-static int errors = 0; // maybe we will use as member of ZIDCache later...
-
-
-/**
- * A poor man's factory.
- *
- * The build process must not allow two cache file implementation classes linked
- * into the same library.
- */
-
-ZIDCache* getZidCacheInstance() {
-
- if (instance == NULL) {
- instance = new ZIDCacheFile();
- }
- return instance;
-}
-
-
-void ZIDCacheFile::createZIDFile(char* name) {
- zidFile = fopen(name, "wb+");
- // New file, generate an associated random ZID and save
- // it as first record
- if (zidFile != NULL) {
- randomZRTP(associatedZid, IDENTIFIER_LEN);
-
- ZIDRecordFile rec;
- rec.setZid(associatedZid);
- rec.setOwnZIDRecord();
- fseek(zidFile, 0L, SEEK_SET);
- if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
- ++errors;
- fflush(zidFile);
- }
-}
-
-/**
- * Migrate old ZID file format to new one.
- *
- * If ZID file is old format:
- * - close it, rename it, then re-open
- * - create ZID file for new format
- * - copy over contents and flags.
- */
-void ZIDCacheFile::checkDoMigration(char* name) {
- FILE* fdOld;
- unsigned char inb[2];
- zidrecord1_t recOld;
-
- fseek(zidFile, 0L, SEEK_SET);
- if (fread(inb, 2, 1, zidFile) < 1) {
- ++errors;
- inb[0] = 0;
- }
-
- if (inb[0] > 0) { // if it's new format just return
- return;
- }
- fclose(zidFile); // close old ZID file
- zidFile = NULL;
-
- // create save file name, rename and re-open
- // if rename fails, just unlink old ZID file and create a brand new file
- // just a little inconvenience for the user, need to verify new SAS
- std::string fn = std::string(name) + std::string(".save");
- if (rename(name, fn.c_str()) < 0) {
- unlink(name);
- createZIDFile(name);
- return;
- }
- fdOld = fopen(fn.c_str(), "rb"); // reopen old format in read only mode
-
- // Get first record from old file - is the own ZID
- fseek(fdOld, 0L, SEEK_SET);
- if (fread(&recOld, sizeof(zidrecord1_t), 1, fdOld) != 1) {
- fclose(fdOld);
- return;
- }
- if (recOld.ownZid != 1) {
- fclose(fdOld);
- return;
- }
- zidFile = fopen(name, "wb+"); // create new format file in binary r/w mode
- if (zidFile == NULL) {
- return;
- }
- // create ZIDRecord in new format, copy over own ZID and write the record
- ZIDRecordFile rec;
- rec.setZid(recOld.identifier);
- rec.setOwnZIDRecord();
- if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
- ++errors;
-
- // now copy over all valid records from old ZID file format.
- // Sequentially read old records, sequentially write new records
- int numRead;
- do {
- numRead = fread(&recOld, sizeof(zidrecord1_t), 1, fdOld);
- if (numRead == 0) { // all old records processed
- break;
- }
- // skip own ZID record and invalid records
- if (recOld.ownZid == 1 || recOld.recValid == 0) {
- continue;
- }
- ZIDRecordFile rec2;
- rec2.setZid(recOld.identifier);
- rec2.setValid();
- if (recOld.rs1Valid & SASVerified) {
- rec2.setSasVerified();
- }
- rec2.setNewRs1(recOld.rs2Data); // TODO: check squenec
- rec2.setNewRs1(recOld.rs1Data);
- if (fwrite(rec2.getRecordData(), rec2.getRecordLength(), 1, zidFile) < 1)
- ++errors;
-
- } while (numRead == 1);
- fflush(zidFile);
-}
-
-ZIDCacheFile::~ZIDCacheFile() {
- close();
-}
-
-int ZIDCacheFile::open(char* name) {
-
- // check for an already active ZID file
- if (zidFile != NULL) {
- return 0;
- }
- if ((zidFile = fopen(name, "rb+")) == NULL) {
- createZIDFile(name);
- } else {
- checkDoMigration(name);
- if (zidFile != NULL) {
- ZIDRecordFile rec;
- fseek(zidFile, 0L, SEEK_SET);
- if (fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) != 1) {
- fclose(zidFile);
- zidFile = NULL;
- return -1;
- }
- if (!rec.isOwnZIDRecord()) {
- fclose(zidFile);
- zidFile = NULL;
- return -1;
- }
- memcpy(associatedZid, rec.getIdentifier(), IDENTIFIER_LEN);
- }
- }
- return ((zidFile == NULL) ? -1 : 1);
-}
-
-void ZIDCacheFile::close() {
-
- if (zidFile != NULL) {
- fclose(zidFile);
- zidFile = NULL;
- }
-}
-
-ZIDRecord *ZIDCacheFile::getRecord(unsigned char *zid) {
- unsigned long pos;
- int numRead;
- // ZIDRecordFile rec;
- ZIDRecordFile *zidRecord = new ZIDRecordFile();
-
- // set read pointer behind first record (
- fseek(zidFile, zidRecord->getRecordLength(), SEEK_SET);
-
- do {
- pos = ftell(zidFile);
- numRead = fread(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile);
- if (numRead == 0) {
- break;
- }
-
- // skip own ZID record and invalid records
- if (zidRecord->isOwnZIDRecord() || !zidRecord->isValid()) {
- continue;
- }
-
- } while (numRead == 1 &&
- memcmp(zidRecord->getIdentifier(), zid, IDENTIFIER_LEN) != 0);
-
- // If we reached end of file, then no record with the ZID
- // found. We need to create a new ZID record.
- if (numRead == 0) {
- // create new record
- // ZIDRecordFile rec1;
- zidRecord->setZid(zid);
- zidRecord->setValid();
- if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
- ++errors;
- }
- // remember position of record in file for save operation
- zidRecord->setPosition(pos);
- return zidRecord;
-}
-
-unsigned int ZIDCacheFile::saveRecord(ZIDRecord *zidRec) {
- ZIDRecordFile *zidRecord = reinterpret_cast<ZIDRecordFile *>(zidRec);
-
- fseek(zidFile, zidRecord->getPosition(), SEEK_SET);
- if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
- ++errors;
- fflush(zidFile);
- return 1;
-}
-
-int32_t ZIDCacheFile::getPeerName(const uint8_t *peerZid, std::string *name) {
- return 0;
-}
-
-void ZIDCacheFile::putPeerName(const uint8_t *peerZid, const std::string name) {
- return;
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
deleted file mode 100644
index b097cbf..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <time.h>
-
-#include <libzrtpcpp/ZIDRecordDb.h>
-
-void ZIDRecordDb::setNewRs1(const unsigned char* data, int32_t expire) {
-
- // shift RS1 data into RS2 position
- memcpy(record.rs2, record.rs1, RS_LENGTH);
- record.rs2Ttl = record.rs1Ttl;
-
- // set new RS1 data
- memcpy(record.rs1, data, RS_LENGTH);
-
- time_t validThru;
- if (expire == -1) {
- validThru = -1;
- }
- else if (expire <= 0) {
- validThru = 0;
- }
- else {
- validThru = time(NULL) + expire;
- }
- record.rs1Ttl = validThru;
- resetRs2Valid();
- setRs1Valid();
-}
-
-
-bool ZIDRecordDb::isRs1NotExpired() {
- time_t current = time(NULL);
- time_t validThru;
-
- validThru = record.rs1Ttl;
-
- if (validThru == -1)
- return true;
- if (validThru == 0)
- return false;
- return (current <= validThru) ? true : false;
-}
-
-bool ZIDRecordDb::isRs2NotExpired() {
- time_t current = time(NULL);
- time_t validThru;
-
- validThru = record.rs2Ttl;
-
- if (validThru == -1)
- return true;
- if (validThru == 0)
- return false;
- return (current <= validThru) ? true : false;
-}
-
-void ZIDRecordDb::setMiTMData(const unsigned char* data) {
- memcpy(record.mitmKey, data, RS_LENGTH);
- setMITMKeyAvailable();
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
deleted file mode 100644
index fd25dec..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <time.h>
-
-#include <libzrtpcpp/ZIDRecordFile.h>
-
-void ZIDRecordFile::setNewRs1(const unsigned char* data, int32_t expire) {
-
- // shift RS1 data into RS2 position
- memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);
- memcpy(record.rs2Interval, record.rs1Interval, TIME_LENGTH);
-
- // set new RS1 data
- memcpy(record.rs1Data, data, RS_LENGTH);
-
- time_t validThru;
- if (expire == -1) {
- validThru = -1;
- }
- else if (expire <= 0) {
- validThru = 0;
- }
- else {
- validThru = time(NULL) + expire;
- }
-
- if (sizeof(time_t) == 4) {
- long long temp = validThru;
- memcpy(record.rs1Interval, (unsigned char*)&temp, TIME_LENGTH);
- }
- else {
- memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);
- }
- resetRs2Valid();
- setRs1Valid();
-}
-
-
-bool ZIDRecordFile::isRs1NotExpired() {
- time_t current = time(NULL);
- time_t validThru;
-
- if (sizeof(time_t) == 4) {
- long long temp;
- memcpy((unsigned char*)&temp, record.rs1Interval, TIME_LENGTH);
- validThru = temp;
- }
- else {
- memcpy((unsigned char*)&validThru, record.rs1Interval, TIME_LENGTH);
- }
-
- if (validThru == -1)
- return true;
- if (validThru == 0)
- return false;
- return (current <= validThru) ? true : false;
-}
-
-bool ZIDRecordFile::isRs2NotExpired() {
- time_t current = time(NULL);
- time_t validThru;
-
- if (sizeof(time_t) == 4) {
- long long temp;
- memcpy((unsigned char*)&temp, record.rs2Interval, TIME_LENGTH);
- validThru = temp;
- }
- else {
- memcpy((unsigned char*)&validThru, record.rs2Interval, TIME_LENGTH);
- }
-
- if (validThru == -1)
- return true;
- if (validThru == 0)
- return false;
- return (current <= validThru) ? true : false;
-}
-
-void ZIDRecordFile::setMiTMData(const unsigned char* data) {
- memcpy(record.mitmKey, data, RS_LENGTH);
- setMITMKeyAvailable();
-}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
deleted file mode 100644
index a6756af..0000000
--- a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <sstream>
-
-#include <libzrtpcpp/ZrtpSdesStream.h>
-#include <libzrtpcpp/ZrtpTextData.h>
-#include <libzrtpcpp/ZrtpConfigure.h>
-#include <libzrtpcpp/zrtpB64Decode.h>
-#include <libzrtpcpp/zrtpB64Encode.h>
-#include <srtp/SrtpHandler.h>
-#include <srtp/CryptoContext.h>
-#include <srtp/CryptoContextCtrl.h>
-#include <cryptcommon/ZrtpRandom.h>
-#include <crypto/hmac384.h>
-
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-// SRTP authentication tag length is 80 bits = 10 bytes
-#define ZRTP_TUNNEL_AUTH_LEN 10
-#define ZRTP_TUNNEL_LABEL 10
-/*
- * The ABNF grammar for the crypto attribute is defined below (from RFC 4568):
- *
- * "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)
- *
- * tag = 1*9DIGIT
- */
-
-/*
- * Buffer size for names and other strings inside the crypto string. The parse
- * format below restricts parsing to 99 char to provide space for the @c nul byte.
- */
-#define MAX_INNER_LEN 100
-
-/*
- * This format scans a received SDES crypto attribute string according to the
- * grammer shown above but without a "a=crypto:" prefix.
- *
- * The format string parses:
- * - %d - the tag as decimal value
- * - %s - the crypto suite name, limited to 99 chars (see MAX_INNER_LEN)
- * - %s - the key parameters, limited to 99 chars
- * - %n - the number of parsed characters to far. The pointer to the session
- * parameters is: cryptoString + numParsedChars.
- */
-static const char parseCrypto[] = "%d %99s %99s %n";
-
-static const int64_t maxTagValue = 999999999;
-
-static const int minElementsCrypto = 3;
-
-/*
- * The ABNF grammar for the key-param (from RFC 4568):
- *
- * key-param = key-method ":" key-info
- *
- * The SRTP specific definitions:
- *
- * key-method = srtp-key-method
- * key-info = srtp-key-info
- *
- * srtp-key-method = "inline"
- * srtp-key-info = key-salt ["|" lifetime] ["|" mki]
- *
- */
-
-/*
- * This format parses the key parameter string which is never longer than
- * 99 chars (see parse string above):
- * - the fixed string "inline:"
- * - %[A-Za-z0-9+/=] - base 64 characters of master key||master salt
- * - the fixed separator character '|'
- * - %[0-9^] - the lifetime infomration as string that contains digits and ^
- * - the fixed separator character '|'
- * - %[0-9]:%d - parses and strore MKI value and MKI length, separated by ':'
- *
- * If the key parameter string does not contain the operional fields lifetime
- * and MKI information the respective parameters are not filled.
- */
-static const char parseKeyParam[] = " inline:%[A-Za-z0-9+/=]|%[0-9^]|%[0-9]:%d";
-
-static const int minElementsKeyParam = 1;
-
-typedef struct _cryptoMix {
- const char* name;
- int32_t hashLength;
- ZrtpSdesStream::sdesHmacTypeMix hashType;
-} cryptoMix;
-
-static const size_t MIX_HMAC_STRING_MIN_LEN = sizeof("HMAC-SHA-384");
-
-static cryptoMix knownMixAlgos[] = {
- {"HMAC-SHA-384", 384, ZrtpSdesStream::MIX_HMAC_SHA},
- {NULL, 0, ZrtpSdesStream::MIX_NONE}
-};
-
-typedef struct _suite {
- ZrtpSdesStream::sdesSuites suite;
- const char *name;
- int32_t keyLength; // key length in bits
- int32_t saltLength; // salt lenght in bits
- int32_t authKeyLength; // authentication key length in bits
- const char *tagLength; // tag type hs80 or hs32
- const char *cipher; // aes1 or aes3
- uint32_t b64length; // length of b64 encoded key/saltstring
- uint64_t defaultSrtpLifetime; // key lifetimes in number of packets
- uint64_t defaultSrtcpLifetime;
-} suiteParam;
-
-/* NOTE: the b64len of a 128 bit suite is 40, a 256bit suite uses 64 characters */
-static suiteParam knownSuites[] = {
- {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_32, "AES_CM_128_HMAC_SHA1_32", 128, 112, 160,
- hs32, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
- },
- {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_80, "AES_CM_128_HMAC_SHA1_80", 128, 112, 160,
- hs80, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
- },
- {(ZrtpSdesStream::sdesSuites)0, NULL, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-ZrtpSdesStream::ZrtpSdesStream(const sdesSuites s) :
- state(STREAM_INITALIZED), suite(s), recvSrtp(NULL), recvSrtcp(NULL), sendSrtp(NULL),
- sendSrtcp(NULL), srtcpIndex(0), recvZrtpTunnel(0), sendZrtpTunnel(0), cryptoMixHashLength(0),
- cryptoMixHashType(MIX_NONE) {
-}
-
-ZrtpSdesStream::~ZrtpSdesStream() {
- close();
-}
-
-void ZrtpSdesStream::close() {
- delete sendSrtp;
- sendSrtp = NULL;
-
- delete recvSrtp;
- recvSrtp = NULL;
-
- delete sendSrtcp;
- sendSrtp = NULL;
-
- delete recvSrtcp;
- recvSrtp = NULL;
-
- delete recvZrtpTunnel;
- recvZrtpTunnel = NULL;
-
- delete sendZrtpTunnel;
- sendZrtpTunnel = NULL;
-}
-
-bool ZrtpSdesStream::createSdes(char *cryptoString, size_t *maxLen, bool sipInvite) {
-
- if (sipInvite) {
- if (state != STREAM_INITALIZED)
- return false;
- tag = 1;
- }
- else {
- if (state != IN_PROFILE_READY)
- return false;
- }
-
- bool s = createSdesProfile(cryptoString, maxLen);
- if (!s)
- return s;
-
- if (sipInvite) {
- state = OUT_PROFILE_READY;
- }
- else {
- createSrtpContexts(sipInvite);
- state = SDES_SRTP_ACTIVE;
- }
- return s;
-}
-
-bool ZrtpSdesStream::parseSdes(const char *cryptoString, size_t length, bool sipInvite) {
-
- if (sipInvite) {
- if (state != OUT_PROFILE_READY)
- return false;
- }
- else {
- if (state != STREAM_INITALIZED)
- return false;
- }
- sdesSuites tmpSuite;
- int32_t tmpTag;
-
- bool s = parseCreateSdesProfile(cryptoString, length, &tmpSuite, &tmpTag);
- if (!s)
- return s;
-
- if (sipInvite) {
- // Check if answerer used same tag and suite as the offerer
- if (tmpTag != tag || suite != tmpSuite)
- return false;
- createSrtpContexts(sipInvite);
- state = SDES_SRTP_ACTIVE;
- }
- else {
- // Answerer stores tag and suite and uses it in createSdesProfile
- suite = tmpSuite;
- tag = tmpTag;
- state = IN_PROFILE_READY;
- }
- return s;
-}
-
-bool ZrtpSdesStream::outgoingRtp(uint8_t *packet, size_t length, size_t *newLength) {
-
- if (state != SDES_SRTP_ACTIVE || sendSrtp == NULL) {
- *newLength = length;
- return true;
- }
- bool rc = SrtpHandler::protect(sendSrtp, packet, length, newLength);
- if (rc)
- ;//protect++;
- return rc;
-}
-
-int ZrtpSdesStream::incomingRtp(uint8_t *packet, size_t length, size_t *newLength) {
- if (state != SDES_SRTP_ACTIVE || recvSrtp == NULL) { // SRTP inactive, just return with newLength set
- *newLength = length;
- return 1;
- }
- int32_t rc = SrtpHandler::unprotect(recvSrtp, packet, length, newLength);
- if (rc == 1) {
-// unprotect++
- }
- else {
-// unprotectFailed++;
- }
- return rc;
-}
-
-
-bool ZrtpSdesStream::outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength) {
-
- if (state != SDES_SRTP_ACTIVE || sendZrtpTunnel == NULL) {
- *newLength = length;
- return true;
- }
- bool rc = SrtpHandler::protect(sendZrtpTunnel, packet, length, newLength);
- if (rc)
- ;//protect++;
- return rc;
-}
-
-int ZrtpSdesStream::incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength) {
- if (state != SDES_SRTP_ACTIVE || recvZrtpTunnel == NULL) { // SRTP inactive, just return with newLength set
- *newLength = length;
- return 1;
- }
- int32_t rc = SrtpHandler::unprotect(recvZrtpTunnel, packet, length, newLength);
- if (rc == 1) {
-// unprotect++
- }
- else {
-// unprotectFailed++;
- }
- return rc;
-}
-
-
-
-bool ZrtpSdesStream::outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength) {
-#if 0
-SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength, uint32_t *srtcpIndex)
-#endif
- return false;
-}
-
-int ZrtpSdesStream::incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength) {
-#if 0
-int32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-#endif
- return 0;
-}
-
-const char* ZrtpSdesStream::getCipher() {
- return knownSuites[suite].cipher;
-}
-
-const char* ZrtpSdesStream::getAuthAlgo() {
- if (strcmp(knownSuites[suite].tagLength, hs80) == 0)
- return "HMAC-SHA1 80 bit";
- else
- return "HMAC-SHA1 32 bit";
-}
-
-int ZrtpSdesStream::getCryptoMixAttribute(char *algoNames, size_t length) {
-
- if (length < MIX_HMAC_STRING_MIN_LEN)
- return 0;
-
- // In case we support more than one MIX profile select the correct one if the
- // application called setCryptoMixAttribute(...) and we already selected the one to use.
- if (cryptoMixHashType != MIX_NONE) {
- for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
- if (cp->hashLength == cryptoMixHashLength && cp->hashType == cryptoMixHashType) {
- strcpy(algoNames, cp->name);
- return strlen(cp->name);
- }
- }
- }
- // TODO: enhance here to support multiple algorithms (concatenate strings into the buffer until buffer full)
- else {
- strcpy(algoNames, knownMixAlgos[0].name);
- return strlen(algoNames);
- }
- return 0;
-}
-
-bool ZrtpSdesStream::setCryptoMixAttribute(const char *algoNames) {
-
- int len = strlen(algoNames);
- if (len <= 0)
- return false;
-
- std::string algoIn(algoNames);
- algoIn += ' ';
-
- // split input name string and lookup if we support one of the offered algorithms
- // We take the first match.
- std::string delimiters = " ";
- size_t current;
- size_t next = -1;
-
- do {
- current = next + 1;
- next = algoIn.find_first_of(delimiters, current);
- if (next == std::string::npos)
- break;
-
- std::string tmps = algoIn.substr(current, next - current );
- const char* nm = tmps.c_str();
-
- for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
- if (strncmp(cp->name, nm, strlen(cp->name)) == 0) {
- cryptoMixHashLength = cp->hashLength;
- cryptoMixHashType = cp->hashType;
- return true;
- }
- }
- } while (true);
-
- return false;
-}
-
-#ifdef WEAKRANDOM
-/*
- * A standard random number generator that uses the portable random() system function.
- *
- * This should be enhanced to use a better random generator
- */
-static int _random(unsigned char *output, size_t len)
-{
- size_t i;
-
- for(i = 0; i < len; ++i )
- output[i] = random();
-
- return( 0 );
-}
-#else
-#include <cryptcommon/ZrtpRandom.h>
-static int _random(unsigned char *output, size_t len)
-{
- return ZrtpRandom::getRandomData(output, len);
-}
-#endif
-
-static int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)
-{
- base64_encodestate _state;
- int codelength;
-
- base64_init_encodestate(&_state, 0);
- codelength = base64_encode_block(binData, binLength, b64Data, &_state);
- codelength += base64_encode_blockend(b64Data+codelength, &_state);
-
- return codelength;
-}
-
-static int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)
-{
- base64_decodestate _state;
- int codelength;
-
- base64_init_decodestate(&_state);
- codelength = base64_decode_block(b64Data, b64length, binData, &_state);
- return codelength;
-}
-
-void* createSha384HmacContext(uint8_t* key, int32_t keyLength);
-void freeSha384HmacContext(void* ctx);
-void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength );
-
-static int expand(uint8_t* prk, uint32_t prkLen, uint8_t* info, int32_t infoLen, int32_t L, uint32_t hashLen, uint8_t* outbuffer)
-{
- int32_t n;
- uint8_t *T;
- void* hmacCtx;
-
- const uint8_t* data[4]; // 3 data pointers for HMAC data plus terminating NULL
- uint32_t dataLen[4];
- int32_t dataIdx = 0;
-
- uint8_t counter;
- int32_t macLength;
-
- if (prkLen < hashLen)
- return -1;
-
- n = (L + (hashLen-1)) / hashLen;
-
- // T points to buffer that holds concatenated T(1) || T(2) || ... T(N))
- T = reinterpret_cast<uint8_t*>(malloc(n * hashLen));
-
- if (hashLen == 384/8)
- hmacCtx = createSha384HmacContext(prk, prkLen);
- else
- return -1;
-
- // Prepare first HMAC. T(0) has zero length, thus we ignore it in first run.
- // After first run use its output (T(1)) as first data in next HMAC run.
- for (int i = 1; i <= n; i++) {
- if (infoLen > 0 && info != NULL) {
- data[dataIdx] = info;
- dataLen[dataIdx++] = infoLen;
- }
- counter = i & 0xff;
- data[dataIdx] = &counter;
- dataLen[dataIdx++] = 1;
-
- data[dataIdx] = NULL;
- dataLen[dataIdx++] = 0;
-
- if (hashLen == 384/8)
- hmacSha384Ctx(hmacCtx, data, dataLen, T + ((i-1) * hashLen), &macLength);
-
- // Use output of previous hash run as first input of next hash run
- dataIdx = 0;
- data[dataIdx] = T + ((i-1) * hashLen);
- dataLen[dataIdx++] = hashLen;
- }
- freeSha384HmacContext(hmacCtx);
- memcpy(outbuffer, T, L);
- free(T);
- return 0;
-}
-
-void ZrtpSdesStream::computeMixedKeys(bool sipInvite) {
- uint8_t salt[MAX_SALT_LEN*2];
- uint8_t ikm[MAX_KEY_LEN*2];
-
- // Concatenate the existing salt and key data. Depending on our role we have to change
- // the order of the data.
- if (sipInvite) { // We are offerer, use local created data as mso and mko, so they go first
- memcpy(salt, &localKeySalt[localKeyLenBytes], localSaltLenBytes);
- memcpy(&salt[localSaltLenBytes], &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);
-
- memcpy(ikm, localKeySalt, localKeyLenBytes);
- memcpy(&ikm[localKeyLenBytes], remoteKeySalt, remoteKeyLenBytes);
- }
- else {
- memcpy(salt, &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);
- memcpy(&salt[remoteSaltLenBytes], &localKeySalt[localKeyLenBytes], localSaltLenBytes);
-
- memcpy(ikm, remoteKeySalt, remoteKeyLenBytes);
- memcpy(&ikm[remoteKeyLenBytes], localKeySalt, localKeyLenBytes);
- }
- uint32_t saltLen = localSaltLenBytes + remoteSaltLenBytes;
- uint32_t keyLen = localKeyLenBytes + remoteKeyLenBytes;
- uint32_t L = saltLen + keyLen;
-
- uint8_t prk[MAX_DIGEST_LENGTH];
- uint32_t prkLen;
-
- switch(cryptoMixHashType) {
- case MIX_HMAC_SHA:
- if (cryptoMixHashLength == 384)
- hmac_sha384(salt, saltLen, ikm, keyLen, prk, &prkLen);
- else
- return;
- break;
-
- case MIX_MAC_SKEIN:
- return;
-
- default:
- return;
- }
-
- uint8_t T[(MAX_SALT_LEN + MAX_KEY_LEN)*2] = {0};
- expand(prk, prkLen, NULL, 0, L, cryptoMixHashLength/8, T);
-
- // We have a new set of SRTP key data now, replace the old with the new.
- int32_t offset = 0;
- if (sipInvite) { // We are offerer, replace local created data with mso and mko, remote with msa, mka
- memcpy(&localKeySalt[localKeyLenBytes], T, localSaltLenBytes);
- offset += localSaltLenBytes;
- memcpy(&remoteKeySalt[remoteKeyLenBytes], &T[offset], remoteSaltLenBytes);
- offset += remoteSaltLenBytes;
-
- memcpy(localKeySalt, &T[offset], localKeyLenBytes);
- offset += localKeyLenBytes;
- memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);
- }
- else { // We are answerer, replace remote data with mso and mko, local data with msa, mka
- memcpy(&remoteKeySalt[remoteKeyLenBytes], T, remoteSaltLenBytes);
- offset += remoteSaltLenBytes;
- memcpy(&localKeySalt[localKeyLenBytes], &T[offset], localSaltLenBytes);
- offset += localSaltLenBytes;
-
- memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);
- offset += remoteKeyLenBytes;
- memcpy(localKeySalt, &T[offset], localKeyLenBytes);
- }
-}
-
-void ZrtpSdesStream::createSrtpContexts(bool sipInvite) {
-
- if (cryptoMixHashType != MIX_NONE) {
- computeMixedKeys(sipInvite);
- }
-
- sendSrtp = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- localCipher, // encryption algo
- localAuthn, // authtentication algo
- localKeySalt, // Master Key
- localKeyLenBytes, // Master Key length
- &localKeySalt[localKeyLenBytes], // Master Salt
- localSaltLenBytes, // Master Salt length
- localKeyLenBytes, // encryption keylen
- localAuthKeyLen, // authentication key len (HMAC key lenght)
- localSaltLenBytes, // session salt len
- localTagLength); // authentication tag len
- sendSrtp->deriveSrtpKeys(0L);
-
- sendZrtpTunnel = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- localCipher, // encryption algo
- localAuthn, // authtentication algo
- localKeySalt, // Master Key
- localKeyLenBytes, // Master Key length
- &localKeySalt[localKeyLenBytes], // Master Salt
- localSaltLenBytes, // Master Salt length
- localKeyLenBytes, // encryption keylen
- localAuthKeyLen, // authentication key len (HMAC key lenght)
- localSaltLenBytes, // session salt len
- ZRTP_TUNNEL_AUTH_LEN); // authentication tag len
-
- sendZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);
- sendZrtpTunnel->deriveSrtpKeys(0L);
- memset(localKeySalt, 0, sizeof(localKeySalt));
-
- recvSrtp = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- remoteCipher, // encryption algo
- remoteAuthn, // authtentication algo
- remoteKeySalt, // Master Key
- remoteKeyLenBytes, // Master Key length
- &remoteKeySalt[remoteKeyLenBytes], // Master Salt
- remoteSaltLenBytes, // Master Salt length
- remoteKeyLenBytes, // encryption keylen
- remoteAuthKeyLen, // authentication key len (HMAC key lenght)
- remoteSaltLenBytes, // session salt len
- remoteTagLength); // authentication tag len
- recvSrtp->deriveSrtpKeys(0L);
-
- recvZrtpTunnel = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- remoteCipher, // encryption algo
- remoteAuthn, // authtentication algo
- remoteKeySalt, // Master Key
- remoteKeyLenBytes, // Master Key length
- &remoteKeySalt[remoteKeyLenBytes], // Master Salt
- remoteSaltLenBytes, // Master Salt length
- remoteKeyLenBytes, // encryption keylen
- remoteAuthKeyLen, // authentication key len (HMAC key lenght)
- remoteSaltLenBytes, // session salt len
- ZRTP_TUNNEL_AUTH_LEN); // authentication tag len
-
- recvZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);
- recvZrtpTunnel->deriveSrtpKeys(0L);
- memset(remoteKeySalt, 0, sizeof(remoteKeySalt));
-}
-
-bool ZrtpSdesStream::createSdesProfile(char *cryptoString, size_t *maxLen) {
-
- char b64keySalt[(MAX_KEY_LEN + MAX_SALT_LEN) * 2] = {'\0'};
- uint32_t sidx;
- int32_t b64Len;
-
- for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) { // Lookup crypto suite parameters
- if (knownSuites[sidx].suite == suite)
- break;
- }
- if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {
- return false;
- }
- suiteParam *pSuite = &knownSuites[sidx];
- _random(localKeySalt, sizeof(localKeySalt));
-
- AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
- localAuthn = SrtpAuthenticationSha1Hmac;
- localAuthKeyLen = pSuite->authKeyLength / 8;
- localTagLength = auth.getKeylen() / 8;
-
- // If SDES will support other encryption algos - get it here based on
- // the algorithm name in suite
- localCipher = SrtpEncryptionAESCM;
-
- localKeyLenBytes = pSuite->keyLength / 8;
- localSaltLenBytes = pSuite->saltLength / 8;
-
- if (tag == -1)
- tag = 1;
-
- // Get B64 code for master key and master salt and then construct the SDES crypto string
- b64Len = b64Encode(localKeySalt, localKeyLenBytes + localSaltLenBytes, b64keySalt, sizeof(b64keySalt));
- b64keySalt[b64Len] = '\0';
- memset(cryptoString, 0, *maxLen);
- *maxLen = snprintf(cryptoString, *maxLen-1, "%d %s inline:%s", tag, pSuite->name, b64keySalt);
-
- return true;
-}
-
-bool ZrtpSdesStream::parseCreateSdesProfile(const char *cryptoStr, size_t length, sdesSuites *parsedSuite, int32_t *outTag) {
- int elements, i;
- int charsScanned;
- int mkiLength = 0;
- uint32_t sidx;
-
- char cryptoString[MAX_CRYPT_STRING_LEN+1] = {'\0'};
-
- /* Parsed strings */
- char suiteName[MAX_INNER_LEN] = {'\0'};
- char keyParams[MAX_INNER_LEN] = {'\0'};
- char keySaltB64[MAX_INNER_LEN] = {'\0'};
- char lifetime[MAX_INNER_LEN] = {'\0'};
- char mkiVal[MAX_INNER_LEN] = {'\0'};
-
- if (length == 0)
- length = strlen(cryptoStr);
-
- if (length > MAX_CRYPT_STRING_LEN) {
- return false;
- }
- memcpy(cryptoString, cryptoStr, length); // make own copy, null terminated
-
- *outTag = -1;
- elements = sscanf(cryptoString, parseCrypto, outTag, suiteName, keyParams, &charsScanned);
-
- if (elements < minElementsCrypto) { // Do we have enough elements in the string
- return false;
- }
-
- for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) { // Lookup crypto suite
- if (!strcmp(knownSuites[sidx].name, suiteName))
- break;
- }
- if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {
- return false;
- }
- suiteParam *pSuite = &knownSuites[sidx];
- *parsedSuite = pSuite->suite;
-
- /* Now scan the key parameters */
- elements = sscanf(keyParams, parseKeyParam, keySaltB64, lifetime, mkiVal, &mkiLength);
-
- if (elements != minElementsKeyParam) { // Currently we only accept key||salt B64 string, no other parameters
- return false;
- }
-
- remoteKeyLenBytes = pSuite->keyLength / 8;
- remoteSaltLenBytes = pSuite->saltLength / 8;
-
- if (strlen(keySaltB64) != pSuite->b64length) { // Check if key||salt B64 string hast the correct length
- return false;
- }
- i = b64Decode(keySaltB64, pSuite->b64length, remoteKeySalt, remoteKeyLenBytes + remoteSaltLenBytes);
-
- if (i != (remoteKeyLenBytes + remoteSaltLenBytes)) { // Did the B64 decode delivered enough data for key||salt
- return false;
- }
-
- AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
- remoteAuthn = SrtpAuthenticationSha1Hmac;
- remoteAuthKeyLen = pSuite->authKeyLength / 8;
- remoteTagLength = auth.getKeylen() / 8;
-
- // If SDES will support other encryption algos - get it here based on
- // the algorithm name in suite
- remoteCipher = SrtpEncryptionAESCM;
-
- return true;
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
deleted file mode 100644
index ecf5b6d..0000000
--- a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-#include <stdint.h>
-#include <libzrtpcpp/ZrtpConfigure.h>
-// 1
-// 1234567890123456
-char clientId[] = "GNU ZRTP 4.1.1 "; // 16 chars max.
-char zrtpVersion_11[] = "1.10"; // must be 4 chars
-char zrtpVersion_12[] = "1.20"; // must be 4 chars
-/**
- *
- */
-char HelloMsg[] = "Hello ";
-char HelloAckMsg[] = "HelloACK";
-char CommitMsg[] = "Commit ";
-char DHPart1Msg[] = "DHPart1 ";
-char DHPart2Msg[] = "DHPart2 ";
-char Confirm1Msg[] = "Confirm1";
-char Confirm2Msg[] = "Confirm2";
-char Conf2AckMsg[] = "Conf2ACK";
-char ErrorMsg[] = "Error ";
-char ErrorAckMsg[] = "ErrorACK";
-char GoClearMsg[] = "GoClear ";
-char ClearAckMsg[] = "ClearACK";
-char PingMsg[] = "Ping ";
-char PingAckMsg[] = "PingACK ";
-char SasRelayMsg[] = "SASrelay";
-char RelayAckMsg[] = "RelayACK";
-
-char responder[] = "Responder";
-char initiator[] = "Initiator";
-char iniMasterKey[] = "Initiator SRTP master key";
-char iniMasterSalt[] = "Initiator SRTP master salt";
-char respMasterKey[] = "Responder SRTP master key";
-char respMasterSalt[] = "Responder SRTP master salt";
-
-char iniHmacKey[] = "Initiator HMAC key";
-char respHmacKey[] = "Responder HMAC key";
-char retainedSec[] = "retained secret";
-
-char iniZrtpKey[] = "Initiator ZRTP key";
-char respZrtpKey[] = "Responder ZRTP key";
-
-char sasString[] = "SAS";
-
-char KDFString[] = "ZRTP-HMAC-KDF";
-
-char zrtpSessionKey[] = "ZRTP Session Key";
-
-char zrtpMsk[] = "ZRTP MSK";
-char zrtpTrustedMitm[] = "Trusted MiTM key";
-
-char s256[] = "S256";
-char s384[] = "S384";
-char skn2[] = "SKN2";
-char skn3[] = "SKN3";
-const char* mandatoryHash = s256;
-
-char aes3[] = "AES3";
-char aes2[] = "AES2";
-char aes1[] = "AES1";
-char two3[] = "2FS3";
-char two2[] = "2FS2";
-char two1[] = "2FS1";
-const char* mandatoryCipher = aes1;
-
-char dh2k[] = "DH2k";
-char ec25[] = "EC25";
-char dh3k[] = "DH3k";
-char ec38[] = "EC38";
-char e255[] = "E255";
-char e414[] = "E414";
-char mult[] = "Mult";
-const char* mandatoryPubKey = dh3k;
-
-char b32[] = "B32 ";
-char b256[] = "B256";
-const char* mandatorySasType = b32;
-
-char hs32[] = "HS32";
-char hs80[] = "HS80";
-char sk32[] = "SK32";
-char sk64[] = "SK64";
-const char* mandatoryAuthLen_1 = hs32;
-const char* mandatoryAuthLen_2 = hs80;
-
-const char* sas256WordsOdd[] = {
- "adroitness",
- "adviser",
- "aftermath",
- "aggregate",
- "alkali",
- "almighty",
- "amulet",
- "amusement",
- "antenna",
- "applicant",
- "Apollo",
- "armistice",
- "article",
- "asteroid",
- "Atlantic",
- "atmosphere",
- "autopsy",
- "Babylon",
- "backwater",
- "barbecue",
- "belowground",
- "bifocals",
- "bodyguard",
- "bookseller",
- "borderline",
- "bottomless",
- "Bradbury",
- "bravado",
- "Brazilian",
- "breakaway",
- "Burlington",
- "businessman",
- "butterfat",
- "Camelot",
- "candidate",
- "cannonball",
- "Capricorn",
- "caravan",
- "caretaker",
- "celebrate",
- "cellulose",
- "certify",
- "chambermaid",
- "Cherokee",
- "Chicago",
- "clergyman",
- "coherence",
- "combustion",
- "commando",
- "company",
- "component",
- "concurrent",
- "confidence",
- "conformist",
- "congregate",
- "consensus",
- "consulting",
- "corporate",
- "corrosion",
- "councilman",
- "crossover",
- "crucifix",
- "cumbersome",
- "customer",
- "Dakota",
- "decadence",
- "December",
- "decimal",
- "designing",
- "detector",
- "detergent",
- "determine",
- "dictator",
- "dinosaur",
- "direction",
- "disable",
- "disbelief",
- "disruptive",
- "distortion",
- "document",
- "embezzle",
- "enchanting",
- "enrollment",
- "enterprise",
- "equation",
- "equipment",
- "escapade",
- "Eskimo",
- "everyday",
- "examine",
- "existence",
- "exodus",
- "fascinate",
- "filament",
- "finicky",
- "forever",
- "fortitude",
- "frequency",
- "gadgetry",
- "Galveston",
- "getaway",
- "glossary",
- "gossamer",
- "graduate",
- "gravity",
- "guitarist",
- "hamburger",
- "Hamilton",
- "handiwork",
- "hazardous",
- "headwaters",
- "hemisphere",
- "hesitate",
- "hideaway",
- "holiness",
- "hurricane",
- "hydraulic",
- "impartial",
- "impetus",
- "inception",
- "indigo",
- "inertia",
- "infancy",
- "inferno",
- "informant",
- "insincere",
- "insurgent",
- "integrate",
- "intention",
- "inventive",
- "Istanbul",
- "Jamaica",
- "Jupiter",
- "leprosy",
- "letterhead",
- "liberty",
- "maritime",
- "matchmaker",
- "maverick",
- "Medusa",
- "megaton",
- "microscope",
- "microwave",
- "midsummer",
- "millionaire",
- "miracle",
- "misnomer",
- "molasses",
- "molecule",
- "Montana",
- "monument",
- "mosquito",
- "narrative",
- "nebula",
- "newsletter",
- "Norwegian",
- "October",
- "Ohio",
- "onlooker",
- "opulent",
- "Orlando",
- "outfielder",
- "Pacific",
- "pandemic",
- "Pandora",
- "paperweight",
- "paragon",
- "paragraph",
- "paramount",
- "passenger",
- "pedigree",
- "Pegasus",
- "penetrate",
- "perceptive",
- "performance",
- "pharmacy",
- "phonetic",
- "photograph",
- "pioneer",
- "pocketful",
- "politeness",
- "positive",
- "potato",
- "processor",
- "provincial",
- "proximate",
- "puberty",
- "publisher",
- "pyramid",
- "quantity",
- "racketeer",
- "rebellion",
- "recipe",
- "recover",
- "repellent",
- "replica",
- "reproduce",
- "resistor",
- "responsive",
- "retraction",
- "retrieval",
- "retrospect",
- "revenue",
- "revival",
- "revolver",
- "sandalwood",
- "sardonic",
- "Saturday",
- "savagery",
- "scavenger",
- "sensation",
- "sociable",
- "souvenir",
- "specialist",
- "speculate",
- "stethoscope",
- "stupendous",
- "supportive",
- "surrender",
- "suspicious",
- "sympathy",
- "tambourine",
- "telephone",
- "therapist",
- "tobacco",
- "tolerance",
- "tomorrow",
- "torpedo",
- "tradition",
- "travesty",
- "trombonist",
- "truncated",
- "typewriter",
- "ultimate",
- "undaunted",
- "underfoot",
- "unicorn",
- "unify",
- "universe",
- "unravel",
- "upcoming",
- "vacancy",
- "vagabond",
- "vertigo",
- "Virginia",
- "visitor",
- "vocalist",
- "voyager",
- "warranty",
- "Waterloo",
- "whimsical",
- "Wichita",
- "Wilmington",
- "Wyoming",
- "yesteryear",
- "Yucatan"
- };
-
-const char* sas256WordsEven[] = {
- "aardvark",
- "absurd",
- "accrue",
- "acme",
- "adrift",
- "adult",
- "afflict",
- "ahead",
- "aimless",
- "Algol",
- "allow",
- "alone",
- "ammo",
- "ancient",
- "apple",
- "artist",
- "assume",
- "Athens",
- "atlas",
- "Aztec",
- "baboon",
- "backfield",
- "backward",
- "banjo",
- "beaming",
- "bedlamp",
- "beehive",
- "beeswax",
- "befriend",
- "Belfast",
- "berserk",
- "billiard",
- "bison",
- "blackjack",
- "blockade",
- "blowtorch",
- "bluebird",
- "bombast",
- "bookshelf",
- "brackish",
- "breadline",
- "breakup",
- "brickyard",
- "briefcase",
- "Burbank",
- "button",
- "buzzard",
- "cement",
- "chairlift",
- "chatter",
- "checkup",
- "chisel",
- "choking",
- "chopper",
- "Christmas",
- "clamshell",
- "classic",
- "classroom",
- "cleanup",
- "clockwork",
- "cobra",
- "commence",
- "concert",
- "cowbell",
- "crackdown",
- "cranky",
- "crowfoot",
- "crucial",
- "crumpled",
- "crusade",
- "cubic",
- "dashboard",
- "deadbolt",
- "deckhand",
- "dogsled",
- "dragnet",
- "drainage",
- "dreadful",
- "drifter",
- "dropper",
- "drumbeat",
- "drunken",
- "Dupont",
- "dwelling",
- "eating",
- "edict",
- "egghead",
- "eightball",
- "endorse",
- "endow",
- "enlist",
- "erase",
- "escape",
- "exceed",
- "eyeglass",
- "eyetooth",
- "facial",
- "fallout",
- "flagpole",
- "flatfoot",
- "flytrap",
- "fracture",
- "framework",
- "freedom",
- "frighten",
- "gazelle",
- "Geiger",
- "glitter",
- "glucose",
- "goggles",
- "goldfish",
- "gremlin",
- "guidance",
- "hamlet",
- "highchair",
- "hockey",
- "indoors",
- "indulge",
- "inverse",
- "involve",
- "island",
- "jawbone",
- "keyboard",
- "kickoff",
- "kiwi",
- "klaxon",
- "locale",
- "lockup",
- "merit",
- "minnow",
- "miser",
- "Mohawk",
- "mural",
- "music",
- "necklace",
- "Neptune",
- "newborn",
- "nightbird",
- "Oakland",
- "obtuse",
- "offload",
- "optic",
- "orca",
- "payday",
- "peachy",
- "pheasant",
- "physique",
- "playhouse",
- "Pluto",
- "preclude",
- "prefer",
- "preshrunk",
- "printer",
- "prowler",
- "pupil",
- "puppy",
- "python",
- "quadrant",
- "quiver",
- "quota",
- "ragtime",
- "ratchet",
- "rebirth",
- "reform",
- "regain",
- "reindeer",
- "rematch",
- "repay",
- "retouch",
- "revenge",
- "reward",
- "rhythm",
- "ribcage",
- "ringbolt",
- "robust",
- "rocker",
- "ruffled",
- "sailboat",
- "sawdust",
- "scallion",
- "scenic",
- "scorecard",
- "Scotland",
- "seabird",
- "select",
- "sentence",
- "shadow",
- "shamrock",
- "showgirl",
- "skullcap",
- "skydive",
- "slingshot",
- "slowdown",
- "snapline",
- "snapshot",
- "snowcap",
- "snowslide",
- "solo",
- "southward",
- "soybean",
- "spaniel",
- "spearhead",
- "spellbind",
- "spheroid",
- "spigot",
- "spindle",
- "spyglass",
- "stagehand",
- "stagnate",
- "stairway",
- "standard",
- "stapler",
- "steamship",
- "sterling",
- "stockman",
- "stopwatch",
- "stormy",
- "sugar",
- "surmount",
- "suspense",
- "sweatband",
- "swelter",
- "tactics",
- "talon",
- "tapeworm",
- "tempest",
- "tiger",
- "tissue",
- "tonic",
- "topmost",
- "tracker",
- "transit",
- "trauma",
- "treadmill",
- "Trojan",
- "trouble",
- "tumor",
- "tunnel",
- "tycoon",
- "uncut",
- "unearth",
- "unwind",
- "uproot",
- "upset",
- "upshot",
- "vapor",
- "village",
- "virus",
- "Vulcan",
- "waffle",
- "wallet",
- "watchword",
- "wayside",
- "willow",
- "woodlark",
- "Zulu"
- };
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp b/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
deleted file mode 100644
index f3042f8..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Copyright (C) 2012-2013 by Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <string.h>
-
-#include <zrtp/crypto/aesCFB.h>
-#include <cryptcommon/aescpp.h>
-
-void aesCfbEncrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
-{
- AESencrypt *saAes = new AESencrypt();
-
- if (keyLength == 16)
- saAes->key128(key);
- else if (keyLength == 32)
- saAes->key256(key);
- else
- return;
-
- // Note: maybe copy IV to an internal array if we encounter strange things.
- // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)
- saAes->cfb_encrypt(data, data, dataLength, IV);
- delete saAes;
-}
-
-
-void aesCfbDecrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
-{
- AESencrypt *saAes = new AESencrypt();
- if (keyLength == 16)
- saAes->key128(key);
- else if (keyLength == 32)
- saAes->key256(key);
- else
- return;
-
- // Note: maybe copy IV to an internal array if we encounter strange things.
- // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)
- saAes->cfb_decrypt(data, data, dataLength, IV);
- delete saAes;
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
deleted file mode 100644
index 1e3ceb7..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "zrtp/crypto/sha2.h"
-#include "zrtp/crypto/hmac256.h"
-
-typedef struct _hmacSha256Context {
- sha256_ctx ctx;
- sha256_ctx innerCtx;
- sha256_ctx outerCtx;
-} hmacSha256Context;
-
-static int32_t hmacSha256Init(hmacSha256Context *ctx, const uint8_t *key, uint32_t kLength)
-{
- int32_t i;
- uint8_t localPad[SHA256_BLOCK_SIZE] = {0};
- uint8_t localKey[SHA256_BLOCK_SIZE] = {0};
-
- if (key == NULL)
- return 0;
-
- memset(ctx, 0, sizeof(hmacSha256Context));
-
- /* check key length and reduce it if necessary */
- if (kLength > SHA256_BLOCK_SIZE) {
- sha256_begin(&ctx->ctx);
- sha256_hash(key, kLength, &ctx->ctx);
- sha256_end(localKey, &ctx->ctx);
- }
- else {
- memcpy(localKey, key, kLength);
- }
- /* prepare inner hash and hold the context */
- for (i = 0; i < SHA256_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x36;
-
- sha256_begin(&ctx->innerCtx);
- sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->innerCtx);
-
- /* prepare outer hash and hold the context */
- for (i = 0; i < SHA256_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x5c;
-
- sha256_begin(&ctx->outerCtx);
- sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->outerCtx);
-
- /* copy prepared inner hash to work hash - ready to process data */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));
-
- memset(localKey, 0, sizeof(localKey));
-
- return 1;
-}
-
-static void hmacSha256Reset(hmacSha256Context *ctx)
-{
- /* copy prepared inner hash to work hash context */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));
-}
-
-static void hmacSha256Update(hmacSha256Context *ctx, const uint8_t *data, uint32_t dLength)
-{
- /* hash new data to work hash context */
- sha256_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha256Final(hmacSha256Context *ctx, uint8_t *mac)
-{
- uint8_t tmpDigest[SHA256_DIGEST_SIZE];
-
- /* finalize work hash context */
- sha256_end(tmpDigest, &ctx->ctx);
-
- /* copy prepared outer hash to work hash */
- memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha256_ctx));
-
- /* hash inner digest to work (outer) hash context */
- sha256_hash(tmpDigest, SHA256_DIGEST_SIZE, &ctx->ctx);
-
- /* finalize work hash context to get the hmac*/
- sha256_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
- hmacSha256Context ctx;
-
- hmacSha256Init(&ctx, key, keyLength);
- hmacSha256Update(&ctx, data, dataLength);
- hmacSha256Final(&ctx, mac);
- *macLength = SHA256_DIGEST_SIZE;
-}
-
-void hmac_sha256(uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
- uint8_t* mac, uint32_t* macLength )
-{
- hmacSha256Context ctx;
-
- hmacSha256Init(&ctx, key, keyLength);
-
- while (*dataChunks) {
- hmacSha256Update(&ctx, *dataChunks, *dataChunckLength);
- dataChunks ++;
- dataChunckLength ++;
- }
- hmacSha256Final(&ctx, mac);
- *macLength = SHA256_DIGEST_SIZE;
-}
-
-void* createSha256HmacContext(uint8_t* key, int32_t keyLength)
-{
- hmacSha256Context *ctx = reinterpret_cast<hmacSha256Context*>(malloc(sizeof(hmacSha256Context)));
-
- hmacSha256Init(ctx, key, keyLength);
- return ctx;
-}
-
-void hmacSha256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
- uint8_t* mac, int32_t* macLength)
-{
- hmacSha256Context *pctx = (hmacSha256Context*)ctx;
-
- hmacSha256Reset(pctx);
- hmacSha256Update(pctx, data, dataLength);
- hmacSha256Final(pctx, mac);
- *macLength = SHA256_DIGEST_SIZE;
-}
-
-void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
- uint8_t* mac, int32_t* macLength )
-{
- hmacSha256Context *pctx = (hmacSha256Context*)ctx;
-
- hmacSha256Reset(pctx);
- while (*data) {
- hmacSha256Update(pctx, *data, *dataLength);
- data++;
- dataLength++;
- }
- hmacSha256Final(pctx, mac);
- *macLength = SHA256_DIGEST_SIZE;
-}
-
-void freeSha256HmacContext(void* ctx)
-{
- if (ctx) {
- memset(ctx, 0, sizeof(hmacSha256Context));
- free(ctx);
- }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
deleted file mode 100644
index c7a7abd..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "zrtp/crypto/sha2.h"
-#include "zrtp/crypto/hmac384.h"
-
-typedef struct _hmacSha384Context {
- sha384_ctx ctx;
- sha384_ctx innerCtx;
- sha384_ctx outerCtx;
-} hmacSha384Context;
-
-static int32_t hmacSha384Init(hmacSha384Context *ctx, const uint8_t *key, uint32_t kLength)
-{
- int32_t i;
- uint8_t localPad[SHA384_BLOCK_SIZE] = {0};
- uint8_t localKey[SHA384_BLOCK_SIZE] = {0};
-
- if (key == NULL)
- return 0;
-
- memset(ctx, 0, sizeof(hmacSha384Context));
-
- /* check key length and reduce it if necessary */
- if (kLength > SHA384_BLOCK_SIZE) {
- sha384_begin(&ctx->ctx);
- sha384_hash(key, kLength, &ctx->ctx);
- sha384_end(localKey, &ctx->ctx);
- }
- else {
- memcpy(localKey, key, kLength);
- }
- /* prepare inner hash and hold the context */
- for (i = 0; i < SHA384_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x36;
-
- sha384_begin(&ctx->innerCtx);
- sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->innerCtx);
-
- /* prepare outer hash and hold the context */
- for (i = 0; i < SHA384_BLOCK_SIZE; i++)
- localPad[i] = localKey[i] ^ 0x5c;
-
- sha384_begin(&ctx->outerCtx);
- sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->outerCtx);
-
- /* copy prepared inner hash to work hash - ready to process data */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));
-
- memset(localKey, 0, sizeof(localKey));
-
- return 1;
-}
-
-static void hmacSha384Reset(hmacSha384Context *ctx)
-{
- /* copy prepared inner hash to work hash context */
- memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));
-}
-
-static void hmacSha384Update(hmacSha384Context *ctx, const uint8_t *data, uint32_t dLength)
-{
- /* hash new data to work hash context */
- sha384_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha384Final(hmacSha384Context *ctx, uint8_t *mac)
-{
- uint8_t tmpDigest[SHA384_DIGEST_SIZE];
-
- /* finalize work hash context */
- sha384_end(tmpDigest, &ctx->ctx);
-
- /* copy prepared outer hash to work hash */
- memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha384_ctx));
-
- /* hash inner digest to work (outer) hash context */
- sha384_hash(tmpDigest, SHA384_DIGEST_SIZE, &ctx->ctx);
-
- /* finalize work hash context to get the hmac*/
- sha384_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
- hmacSha384Context ctx;
-
- hmacSha384Init(&ctx, key, keyLength);
- hmacSha384Update(&ctx, data, dataLength);
- hmacSha384Final(&ctx, mac);
- *macLength = SHA384_DIGEST_SIZE;
-}
-
-void hmac_sha384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
- uint8_t* mac, uint32_t* macLength )
-{
- hmacSha384Context ctx;
-
- hmacSha384Init(&ctx, key, keyLength);
-
- while (*dataChunks) {
- hmacSha384Update(&ctx, *dataChunks, *dataChunckLength);
- dataChunks ++;
- dataChunckLength ++;
- }
- hmacSha384Final(&ctx, mac);
- *macLength = SHA384_DIGEST_SIZE;
-}
-
-void* createSha384HmacContext(uint8_t* key, int32_t keyLength)
-{
- hmacSha384Context *ctx = reinterpret_cast<hmacSha384Context*>(malloc(sizeof(hmacSha384Context)));
-
- hmacSha384Init(ctx, key, keyLength);
- return ctx;
-}
-
-void hmacSha384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
- uint8_t* mac, int32_t* macLength)
-{
- hmacSha384Context *pctx = (hmacSha384Context*)ctx;
-
- hmacSha384Reset(pctx);
- hmacSha384Update(pctx, data, dataLength);
- hmacSha384Final(pctx, mac);
- *macLength = SHA384_DIGEST_SIZE;
-}
-
-void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
- uint8_t* mac, int32_t* macLength )
-{
- hmacSha384Context *pctx = (hmacSha384Context*)ctx;
-
- hmacSha384Reset(pctx);
- while (*data) {
- hmacSha384Update(pctx, *data, *dataLength);
- data++;
- dataLength++;
- }
- hmacSha384Final(pctx, mac);
- *macLength = SHA384_DIGEST_SIZE;
-}
-
-void freeSha384HmacContext(void* ctx)
-{
- if (ctx) {
- memset(ctx, 0, sizeof(hmacSha384Context));
- free(ctx);
- }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.c b/jni/libzrtp/sources/zrtp/crypto/sha2.c
deleted file mode 100644
index 22761f3..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-
- This is a byte oriented version of SHA2 that operates on arrays of bytes
- stored in memory. This code implements sha256, sha384 and sha512 but the
- latter two functions rely on efficient 64-bit integer operations that
- may not be very efficient on 32-bit machines
-
- The sha256 functions use a type 'sha256_ctx' to hold details of the
- current hash state and uses the following three calls:
-
- void sha256_begin(sha256_ctx ctx[1])
- void sha256_hash(const unsigned char data[],
- unsigned long len, sha256_ctx ctx[1])
- void sha_end1(unsigned char hval[], sha256_ctx ctx[1])
-
- The first subroutine initialises a hash computation by setting up the
- context in the sha256_ctx context. The second subroutine hashes 8-bit
- bytes from array data[] into the hash state withinh sha256_ctx context,
- the number of bytes to be hashed being given by the the unsigned long
- integer len. The third subroutine completes the hash calculation and
- places the resulting digest value in the array of 8-bit bytes hval[].
-
- The sha384 and sha512 functions are similar and use the interfaces:
-
- void sha384_begin(sha384_ctx ctx[1]);
- void sha384_hash(const unsigned char data[],
- unsigned long len, sha384_ctx ctx[1]);
- void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
-
- void sha512_begin(sha512_ctx ctx[1]);
- void sha512_hash(const unsigned char data[],
- unsigned long len, sha512_ctx ctx[1]);
- void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
-
- In addition there is a function sha2 that can be used to call all these
- functions using a call with a hash length parameter as follows:
-
- int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
- void sha2_hash(const unsigned char data[],
- unsigned long len, sha2_ctx ctx[1]);
- void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
-
- My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
- on big-endian systems and for his assistance with corrections
-*/
-
-#if 0
-#define UNROLL_SHA2 /* for SHA2 loop unroll */
-#endif
-
-#include <string.h> /* for memcpy() etc. */
-
-#include "sha2.h"
-
-#include <cryptcommon/brg_endian.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#if 0 && defined(_MSC_VER)
-#define rotl32 _lrotl
-#define rotr32 _lrotr
-#else
-#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
-#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
-#endif
-
-#if !defined(bswap_32)
-#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
-#endif
-
-#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
-#define SWAP_BYTES
-#else
-#undef SWAP_BYTES
-#endif
-
-#if 0
-
-#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
-#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */
-
-#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
-#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
-
-#endif
-
-/* round transforms for SHA256 and SHA512 compression functions */
-
-#define vf(n,i) v[(n - i) & 7]
-
-#define hf(i) (p[i & 15] += \
- g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
-
-#define v_cycle(i,j) \
- vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \
- + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \
- vf(3,i) += vf(7,i); \
- vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
-
-#if defined(SHA_224) || defined(SHA_256)
-
-#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
-
-#if defined(SWAP_BYTES)
-#define bsw_32(p,n) \
- { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
-#else
-#define bsw_32(p,n)
-#endif
-
-#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22))
-#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25))
-#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3))
-#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
-#define k_0 k256
-
-/* rotated SHA256 round definition. Rather than swapping variables as in */
-/* FIPS-180, different variables are 'rotated' on each round, returning */
-/* to their starting positions every eight rounds */
-
-#define q(n) v##n
-
-#define one_cycle(a,b,c,d,e,f,g,h,k,w) \
- q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
- q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
-
-/* SHA256 mixing data */
-
-const uint_32t k256[64] =
-{ 0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
- 0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
- 0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
- 0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,
- 0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,
- 0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,
- 0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,
- 0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,
- 0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,
- 0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,
- 0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,
- 0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,
- 0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,
- 0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,
- 0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,
- 0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,
-};
-
-/* Compile 64 bytes of hash data into SHA256 digest value */
-/* NOTE: this routine assumes that the byte order in the */
-/* ctx->wbuf[] at this point is such that low address bytes */
-/* in the ORIGINAL byte stream will go into the high end of */
-/* words on BOTH big and little endian systems */
-
-VOID_RETURN sha256_compile(sha256_ctx ctx[1])
-{
-#if !defined(UNROLL_SHA2)
-
- uint_32t j, *p = ctx->wbuf, v[8];
-
- memcpy(v, ctx->hash, 8 * sizeof(uint_32t));
-
- for(j = 0; j < 64; j += 16)
- {
- v_cycle( 0, j); v_cycle( 1, j);
- v_cycle( 2, j); v_cycle( 3, j);
- v_cycle( 4, j); v_cycle( 5, j);
- v_cycle( 6, j); v_cycle( 7, j);
- v_cycle( 8, j); v_cycle( 9, j);
- v_cycle(10, j); v_cycle(11, j);
- v_cycle(12, j); v_cycle(13, j);
- v_cycle(14, j); v_cycle(15, j);
- }
-
- ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
- ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
- ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
- ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
-
-#else
-
- uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
-
- v0 = ctx->hash[0]; v1 = ctx->hash[1];
- v2 = ctx->hash[2]; v3 = ctx->hash[3];
- v4 = ctx->hash[4]; v5 = ctx->hash[5];
- v6 = ctx->hash[6]; v7 = ctx->hash[7];
-
- one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);
- one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);
- one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);
- one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);
- one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);
- one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);
- one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);
- one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);
- one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);
- one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);
- one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);
- one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);
- one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);
- one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);
- one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);
- one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);
-
- one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));
- one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));
- one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));
- one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));
- one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));
- one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));
- one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));
- one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));
- one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));
- one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));
- one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));
- one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));
- one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));
- one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));
- one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));
- one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));
-
- one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));
- one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));
- one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));
- one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));
- one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));
- one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));
- one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));
- one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));
- one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));
- one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));
- one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));
- one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));
- one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));
- one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));
- one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));
- one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));
-
- one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));
- one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));
- one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));
- one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));
- one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));
- one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));
- one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));
- one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));
- one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));
- one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));
- one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));
- one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));
- one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));
- one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));
- one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));
- one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));
-
- ctx->hash[0] += v0; ctx->hash[1] += v1;
- ctx->hash[2] += v2; ctx->hash[3] += v3;
- ctx->hash[4] += v4; ctx->hash[5] += v5;
- ctx->hash[6] += v6; ctx->hash[7] += v7;
-#endif
-}
-
-/* SHA256 hash data in an array of bytes into hash buffer */
-/* and call the hash_compile function as required. */
-
-VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
-{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK),
- space = SHA256_BLOCK_SIZE - pos;
- const unsigned char *sp = data;
-
- if((ctx->count[0] += len) < len)
- ++(ctx->count[1]);
-
- while(len >= space) /* tranfer whole blocks while possible */
- {
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
- sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;
- bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
- sha256_compile(ctx);
- }
-
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA256 Final padding and digest calculation */
-
-static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
-{ uint_32t i = (uint_32t)(ctx->count[0] & SHA256_MASK);
-
- /* put bytes in the buffer in an order in which references to */
- /* 32-bit words will put bytes with lower addresses into the */
- /* top of 32 bit words on BOTH big and little endian machines */
- bsw_32(ctx->wbuf, (i + 3) >> 2)
-
- /* we now need to mask valid bytes and add the padding which is */
- /* a single 1 bit and as many zero bits as necessary. Note that */
- /* we can always add the first padding byte here because the */
- /* buffer always has at least one empty slot */
- ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
- ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
-
- /* we need 9 or more empty positions, one for the padding byte */
- /* (above) and eight for the length count. If there is not */
- /* enough space pad and empty the buffer */
- if(i > SHA256_BLOCK_SIZE - 9)
- {
- if(i < 60) ctx->wbuf[15] = 0;
- sha256_compile(ctx);
- i = 0;
- }
- else /* compute a word index for the empty buffer positions */
- i = (i >> 2) + 1;
-
- while(i < 14) /* and zero pad all but last two positions */
- ctx->wbuf[i++] = 0;
-
- /* the following 32-bit length fields are assembled in the */
- /* wrong byte order on little endian machines but this is */
- /* corrected later since they are only ever used as 32-bit */
- /* word values. */
- ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
- ctx->wbuf[15] = ctx->count[0] << 3;
- sha256_compile(ctx);
-
- /* extract the hash value as bytes in case the hash buffer is */
- /* mislaigned for 32-bit words */
- for(i = 0; i < hlen; ++i)
- hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
-}
-
-#endif
-
-#if defined(SHA_224)
-
-const uint_32t i224[8] =
-{
- 0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
- 0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
-};
-
-VOID_RETURN sha224_begin(sha224_ctx ctx[1])
-{
- ctx->count[0] = ctx->count[1] = 0;
- memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));
-}
-
-VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
-{
- sha_end1(hval, ctx, SHA224_DIGEST_SIZE);
-}
-
-VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len)
-{ sha224_ctx cx[1];
-
- sha224_begin(cx);
- sha224_hash(data, len, cx);
- sha_end1(hval, cx, SHA224_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_256)
-
-const uint_32t i256[8] =
-{
- 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
- 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
-};
-
-VOID_RETURN sha256_begin(sha256_ctx ctx[1])
-{
- ctx->count[0] = ctx->count[1] = 0;
- memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));
-}
-
-VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
-{
- sha_end1(hval, ctx, SHA256_DIGEST_SIZE);
-}
-
-VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len)
-{ sha256_ctx cx[1];
-
- sha256_begin(cx);
- sha256_hash(data, len, cx);
- sha_end1(hval, cx, SHA256_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_384) || defined(SHA_512)
-
-#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
-
-#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
-
-#if !defined(bswap_64)
-#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))
-#endif
-
-#if defined(SWAP_BYTES)
-#define bsw_64(p,n) \
- { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }
-#else
-#define bsw_64(p,n)
-#endif
-
-/* SHA512 mixing function definitions */
-
-#ifdef s_0
-# undef s_0
-# undef s_1
-# undef g_0
-# undef g_1
-# undef k_0
-#endif
-
-#define s_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
-#define s_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
-#define g_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7))
-#define g_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6))
-#define k_0 k512
-
-/* SHA384/SHA512 mixing data */
-
-const uint_64t k512[80] =
-{
- li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
- li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
- li_64(3956c25bf348b538), li_64(59f111f1b605d019),
- li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),
- li_64(d807aa98a3030242), li_64(12835b0145706fbe),
- li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),
- li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),
- li_64(9bdc06a725c71235), li_64(c19bf174cf692694),
- li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),
- li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),
- li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),
- li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),
- li_64(983e5152ee66dfab), li_64(a831c66d2db43210),
- li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),
- li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),
- li_64(06ca6351e003826f), li_64(142929670a0e6e70),
- li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),
- li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),
- li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),
- li_64(81c2c92e47edaee6), li_64(92722c851482353b),
- li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),
- li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),
- li_64(d192e819d6ef5218), li_64(d69906245565a910),
- li_64(f40e35855771202a), li_64(106aa07032bbd1b8),
- li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),
- li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),
- li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),
- li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),
- li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),
- li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),
- li_64(90befffa23631e28), li_64(a4506cebde82bde9),
- li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),
- li_64(ca273eceea26619c), li_64(d186b8c721c0c207),
- li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),
- li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),
- li_64(113f9804bef90dae), li_64(1b710b35131c471b),
- li_64(28db77f523047d84), li_64(32caab7b40c72493),
- li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),
- li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),
- li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)
-};
-
-/* Compile 128 bytes of hash data into SHA384/512 digest */
-/* NOTE: this routine assumes that the byte order in the */
-/* ctx->wbuf[] at this point is such that low address bytes */
-/* in the ORIGINAL byte stream will go into the high end of */
-/* words on BOTH big and little endian systems */
-
-VOID_RETURN sha512_compile(sha512_ctx ctx[1])
-{ uint_64t v[8], *p = ctx->wbuf;
- uint_32t j;
-
- memcpy(v, ctx->hash, 8 * sizeof(uint_64t));
-
- for(j = 0; j < 80; j += 16)
- {
- v_cycle( 0, j); v_cycle( 1, j);
- v_cycle( 2, j); v_cycle( 3, j);
- v_cycle( 4, j); v_cycle( 5, j);
- v_cycle( 6, j); v_cycle( 7, j);
- v_cycle( 8, j); v_cycle( 9, j);
- v_cycle(10, j); v_cycle(11, j);
- v_cycle(12, j); v_cycle(13, j);
- v_cycle(14, j); v_cycle(15, j);
- }
-
- ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
- ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
- ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
- ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
-}
-
-/* Compile 128 bytes of hash data into SHA256 digest value */
-/* NOTE: this routine assumes that the byte order in the */
-/* ctx->wbuf[] at this point is in such an order that low */
-/* address bytes in the ORIGINAL byte stream placed in this */
-/* buffer will now go to the high end of words on BOTH big */
-/* and little endian systems */
-
-VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
-{ uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK),
- space = SHA512_BLOCK_SIZE - pos;
- const unsigned char *sp = data;
-
- if((ctx->count[0] += len) < len)
- ++(ctx->count[1]);
-
- while(len >= space) /* tranfer whole blocks while possible */
- {
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
- sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;
- bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);
- sha512_compile(ctx);
- }
-
- memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA384/512 Final padding and digest calculation */
-
-static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
-{ uint_32t i = (uint_32t)(ctx->count[0] & SHA512_MASK);
-
- /* put bytes in the buffer in an order in which references to */
- /* 32-bit words will put bytes with lower addresses into the */
- /* top of 32 bit words on BOTH big and little endian machines */
- bsw_64(ctx->wbuf, (i + 7) >> 3);
-
- /* we now need to mask valid bytes and add the padding which is */
- /* a single 1 bit and as many zero bits as necessary. Note that */
- /* we can always add the first padding byte here because the */
- /* buffer always has at least one empty slot */
- ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7);
- ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7);
-
- /* we need 17 or more empty byte positions, one for the padding */
- /* byte (above) and sixteen for the length count. If there is */
- /* not enough space pad and empty the buffer */
- if(i > SHA512_BLOCK_SIZE - 17)
- {
- if(i < 120) ctx->wbuf[15] = 0;
- sha512_compile(ctx);
- i = 0;
- }
- else
- i = (i >> 3) + 1;
-
- while(i < 14)
- ctx->wbuf[i++] = 0;
-
- /* the following 64-bit length fields are assembled in the */
- /* wrong byte order on little endian machines but this is */
- /* corrected later since they are only ever used as 64-bit */
- /* word values. */
- ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
- ctx->wbuf[15] = ctx->count[0] << 3;
- sha512_compile(ctx);
-
- /* extract the hash value as bytes in case the hash buffer is */
- /* misaligned for 32-bit words */
- for(i = 0; i < hlen; ++i)
- hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
-}
-
-#endif
-
-#if defined(SHA_384)
-
-/* SHA384 initialisation data */
-
-const uint_64t i384[80] =
-{
- li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
- li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
- li_64(67332667ffc00b31), li_64(8eb44a8768581511),
- li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)
-};
-
-VOID_RETURN sha384_begin(sha384_ctx ctx[1])
-{
- ctx->count[0] = ctx->count[1] = 0;
- memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));
-}
-
-VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
-{
- sha_end2(hval, ctx, SHA384_DIGEST_SIZE);
-}
-
-VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
-{ sha384_ctx cx[1];
-
- sha384_begin(cx);
- sha384_hash(data, len, cx);
- sha_end2(hval, cx, SHA384_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_512)
-
-/* SHA512 initialisation data */
-
-const uint_64t i512[80] =
-{
- li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
- li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
- li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),
- li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
-};
-
-VOID_RETURN sha512_begin(sha512_ctx ctx[1])
-{
- ctx->count[0] = ctx->count[1] = 0;
- memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));
-}
-
-VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
-{
- sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
-}
-
-VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
-{ sha512_ctx cx[1];
-
- sha512_begin(cx);
- sha512_hash(data, len, cx);
- sha_end2(hval, cx, SHA512_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_2)
-
-#define CTX_224(x) ((x)->uu->ctx256)
-#define CTX_256(x) ((x)->uu->ctx256)
-#define CTX_384(x) ((x)->uu->ctx512)
-#define CTX_512(x) ((x)->uu->ctx512)
-
-/* SHA2 initialisation */
-
-INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])
-{
- switch(len)
- {
-#if defined(SHA_224)
- case 224:
- case 28: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
- memcpy(CTX_256(ctx)->hash, i224, 32);
- ctx->sha2_len = 28; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_256)
- case 256:
- case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
- memcpy(CTX_256(ctx)->hash, i256, 32);
- ctx->sha2_len = 32; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_384)
- case 384:
- case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
- memcpy(CTX_384(ctx)->hash, i384, 64);
- ctx->sha2_len = 48; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_512)
- case 512:
- case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
- memcpy(CTX_512(ctx)->hash, i512, 64);
- ctx->sha2_len = 64; return EXIT_SUCCESS;
-#endif
- default: return EXIT_FAILURE;
- }
-}
-
-VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
-{
- switch(ctx->sha2_len)
- {
-#if defined(SHA_224)
- case 28: sha224_hash(data, len, CTX_224(ctx)); return;
-#endif
-#if defined(SHA_256)
- case 32: sha256_hash(data, len, CTX_256(ctx)); return;
-#endif
-#if defined(SHA_384)
- case 48: sha384_hash(data, len, CTX_384(ctx)); return;
-#endif
-#if defined(SHA_512)
- case 64: sha512_hash(data, len, CTX_512(ctx)); return;
-#endif
- }
-}
-
-VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])
-{
- switch(ctx->sha2_len)
- {
-#if defined(SHA_224)
- case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_256)
- case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_384)
- case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_512)
- case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
-#endif
- }
-}
-
-INT_RETURN sha2_all(unsigned char hval[], unsigned long size,
- const unsigned char data[], unsigned long len)
-{ sha2_ctx cx[1];
-
- if(sha2_begin(size, cx) == EXIT_SUCCESS)
- {
- sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;
- }
- else
- return EXIT_FAILURE;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.h b/jni/libzrtp/sources/zrtp/crypto/sha2.h
deleted file mode 100644
index 1ad3889..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
- 1. distributions of this source code include the above copyright
- notice, this list of conditions and the following disclaimer;
-
- 2. distributions in binary form include the above copyright
- notice, this list of conditions and the following disclaimer
- in the documentation and/or other associated materials;
-
- 3. the copyright holder's name is not used to endorse products
- built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-*/
-
-#ifndef _SHA2_H
-#define _SHA2_H
-
-#include <stdlib.h>
-
-#define SHA_64BIT
-
-/* define the hash functions that you need */
-#define SHA_2 /* for dynamic hash length */
-#define SHA_224
-#define SHA_256
-#ifdef SHA_64BIT
-# define SHA_384
-# define SHA_512
-# define NEED_UINT_64T
-#endif
-
-#include <cryptcommon/brg_types.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Note that the following function prototypes are the same */
-/* for both the bit and byte oriented implementations. But */
-/* the length fields are in bytes or bits as is appropriate */
-/* for the version used. Bit sequences are arrays of bytes */
-/* in which bit sequence indexes increase from the most to */
-/* the least significant end of each byte */
-
-#define SHA224_DIGEST_SIZE 28
-#define SHA224_BLOCK_SIZE 64
-#define SHA256_DIGEST_SIZE 32
-#define SHA256_BLOCK_SIZE 64
-
-/* type to hold the SHA256 (and SHA224) context */
-
-typedef struct
-{ uint_32t count[2];
- uint_32t hash[8];
- uint_32t wbuf[16];
-} sha256_ctx;
-
-typedef sha256_ctx sha224_ctx;
-
-VOID_RETURN sha256_compile(sha256_ctx ctx[1]);
-
-VOID_RETURN sha224_begin(sha224_ctx ctx[1]);
-#define sha224_hash sha256_hash
-VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]);
-VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-VOID_RETURN sha256_begin(sha256_ctx ctx[1]);
-VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]);
-VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]);
-VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-#ifndef SHA_64BIT
-
-typedef struct
-{ union
- { sha256_ctx ctx256[1];
- } uu[1];
- uint_32t sha2_len;
-} sha2_ctx;
-
-#define SHA2_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
-
-#else
-
-#define SHA384_DIGEST_SIZE 48
-#define SHA384_BLOCK_SIZE 128
-#define SHA512_DIGEST_SIZE 64
-#define SHA512_BLOCK_SIZE 128
-#define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
-
-/* type to hold the SHA384 (and SHA512) context */
-
-typedef struct
-{ uint_64t count[2];
- uint_64t hash[8];
- uint_64t wbuf[16];
-} sha512_ctx;
-
-typedef sha512_ctx sha384_ctx;
-
-typedef struct
-{ union
- { sha256_ctx ctx256[1];
- sha512_ctx ctx512[1];
- } uu[1];
- uint_32t sha2_len;
-} sha2_ctx;
-
-VOID_RETURN sha512_compile(sha512_ctx ctx[1]);
-
-VOID_RETURN sha384_begin(sha384_ctx ctx[1]);
-#define sha384_hash sha512_hash
-VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
-VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-VOID_RETURN sha512_begin(sha512_ctx ctx[1]);
-VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]);
-VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
-VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-INT_RETURN sha2_begin(unsigned long size, sha2_ctx ctx[1]);
-VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
-VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
-INT_RETURN sha2_all(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha256.cpp b/jni/libzrtp/sources/zrtp/crypto/sha256.cpp
deleted file mode 100644
index 593b5e5..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <zrtp/crypto/sha2.h>
-#include <zrtp/crypto/sha256.h>
-
-void sha256(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
- sha256_ctx ctx;
-
- sha256_begin(&ctx);
- sha256_hash(data, dataLength, &ctx);
- sha256_end(digest, &ctx);
-}
-
-void sha256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
- sha256_ctx ctx;
-
- sha256_begin(&ctx);
- while(*dataChunks) {
- sha256_hash(*dataChunks, *dataChunckLength, &ctx);
- dataChunks++;
- dataChunckLength++;
- }
- sha256_end(digest, &ctx);
-}
-
-void* createSha256Context()
-{
- sha256_ctx *ctx = reinterpret_cast<sha256_ctx*>(malloc(sizeof(sha256_ctx)));
- sha256_begin(ctx);
- return (void*)ctx;
-}
-
-void closeSha256Context(void* ctx, unsigned char* digest)
-{
- sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
- if (digest != NULL) {
- sha256_end(digest, hd);
- }
- free(hd);
-}
-
-void sha256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
- sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
- sha256_hash(data, dataLength, hd);
-}
-
-void sha256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
- sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
- while (*dataChunks) {
- sha256_hash(*dataChunks, *dataChunkLength, hd);
- dataChunks++;
- dataChunkLength++;
- }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.cpp b/jni/libzrtp/sources/zrtp/crypto/sha384.cpp
deleted file mode 100644
index d6b9085..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Copyright (C) 2012 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <zrtp/crypto/sha2.h>
-#include <zrtp/crypto/sha384.h>
-
-void sha384(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
- sha384_ctx ctx;
-
- sha384_begin(&ctx);
- sha384_hash(data, dataLength, &ctx);
- sha384_end(digest, &ctx);
-}
-
-void sha384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
- sha384_ctx ctx;
-
- sha384_begin(&ctx);
- while(*dataChunks) {
- sha384_hash(*dataChunks, *dataChunckLength, &ctx);
- dataChunks++;
- dataChunckLength++;
- }
- sha384_end(digest, &ctx);
-}
-
-void* createSha384Context()
-{
- sha384_ctx *ctx = reinterpret_cast<sha384_ctx*>(malloc(sizeof(sha384_ctx)));
- sha384_begin(ctx);
- return (void*)ctx;
-}
-
-void closeSha384Context(void* ctx, unsigned char* digest)
-{
- sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
- if (digest != NULL) {
- sha384_end(digest, hd);
- }
- free(hd);
-}
-
-void sha384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
- sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
- sha384_hash(data, dataLength, hd);
-}
-
-void sha384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
- sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
- while (*dataChunks) {
- sha384_hash(*dataChunks, *dataChunkLength, hd);
- dataChunks++;
- dataChunkLength++;
- }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp b/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
deleted file mode 100644
index 94cff63..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein256.h>
-
-#include <stdlib.h>
-
-void skein256(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
- SkeinCtx_t ctx;
-
- skeinCtxPrepare(&ctx, SKEIN_SIZE);
- skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
- skeinUpdate(&ctx, data, dataLength);
-
- skeinFinal(&ctx, digest);
-}
-
-void skein256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
- SkeinCtx_t ctx;
-
- skeinCtxPrepare(&ctx, SKEIN_SIZE);
- skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
- while(*dataChunks) {
- skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
- dataChunks++;
- dataChunckLength++;
- }
- skeinFinal(&ctx, digest);
-}
-
-void* createSkein256Context()
-{
- SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
- skeinCtxPrepare(ctx, SKEIN_SIZE);
- skeinInit(ctx, SKEIN256_DIGEST_LENGTH*8);
- return (void*)ctx;
-}
-
-void closeSkein256Context(void* ctx, unsigned char* digest)
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- if (digest != NULL) {
- skeinFinal(hd, digest);
- }
- free(hd);
-}
-
-void skein256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- skeinUpdate(hd, data, dataLength);
-}
-
-void skein256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- while (*dataChunks) {
- skeinUpdate(hd, *dataChunks, *dataChunkLength);
- dataChunks++;
- dataChunkLength++;
- }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.h b/jni/libzrtp/sources/zrtp/crypto/skein256.h
deleted file mode 100644
index 6d4e722..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein256 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN256_H
-#define _SKEIN256_H
-
-/**
- * @file skein256.h
- * @brief Functions that provide Skein256 support
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH 32
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein256 digest.
- *
- * This functions takes one data chunk and computes its Skein256 digest. This
- * function creates and deletes an own Skein256 context to perform the Skein256
- * operations.
- *
- * @param data
- * Points to the data chunk.
- * @param data_length
- * Length of the data in bytes
- * @param digest
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data,
- unsigned int data_length,
- unsigned char *digest);
-
-/**
- * Compute Skein256 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein256 digest.
- * This function creates and deletes an own Skein256 context to perform the
- * Skein256 operations.
- *
- * @param data
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param data_length
- * Points to an array of integers that hold the length of each data chunk.
- * @param digest
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data[],
- unsigned int data_length[],
- unsigned char *digest);
-/**
- * Create and initialize a Skein256 context.
- *
- * An application uses this context to hash several data into one Skein256
- * digest. See also skein256Ctx(...) and closeSha256Context(...).
- *
- * @return Returns a pointer to the initialized Skein256 context
- */
-void* createSkein256Context();
-
-/**
- * Compute a digest and close the SHa256 digest.
- *
- * An application uses this function to compute the Skein256 digest and to
- * close the Skein256 context.
- *
- * @param ctx
- * Points to the Skein256 context.
- * @param digest
- * If this pointer is not NULL then it must point to a byte array that
- * is big enough to hold the Skein256 digest (256 bit = 32 Bytes). If this
- * pointer is NULL then the functions does not compute the digest but
- * closes the context only. The context cannot be used anymore.
- */
-void closeSkein256Context(void* ctx,
- unsigned char* digest);
-
-/**
- * Update the Skein256 context with data.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- * Points to the Skein256 context.
- * @param data
- * Points to the data to update the context.
- * @param dataLength
- * The length of the data in bytes.
- */
-void skein256Ctx(void* ctx, unsigned char* data,
- unsigned int dataLength);
-
-/**
- * Update the Skein256 context with several data chunks.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- * Points to the Skein256 context.
- * @param dataChunks
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- * Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein256Ctx(void* ctx, unsigned char* dataChunks[],
- unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp b/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
deleted file mode 100644
index 1dbe608..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein384.h>
-
-#include <stdlib.h>
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH 48
-
-void skein384(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
- SkeinCtx_t ctx;
-
- skeinCtxPrepare(&ctx, SKEIN_SIZE);
- skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
- skeinUpdate(&ctx, data, dataLength);
-
- skeinFinal(&ctx, digest);
-}
-
-void skein384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
- SkeinCtx_t ctx;
-
- skeinCtxPrepare(&ctx, SKEIN_SIZE);
- skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
- while(*dataChunks) {
- skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
- dataChunks++;
- dataChunckLength++;
- }
- skeinFinal(&ctx, digest);
-}
-
-void* createSkein384Context()
-{
- SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
- skeinCtxPrepare(ctx, SKEIN_SIZE);
- skeinInit(ctx, SKEIN384_DIGEST_LENGTH*8);
- return (void*)ctx;
-}
-
-void closeSkein384Context(void* ctx, unsigned char* digest)
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- if (digest != NULL) {
- skeinFinal(hd, digest);
- }
- free(hd);
-}
-
-void skein384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- skeinUpdate(hd, data, dataLength);
-}
-
-void skein384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
- SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
- while (*dataChunks) {
- skeinUpdate(hd, *dataChunks, *dataChunkLength);
- dataChunks++;
- dataChunkLength++;
- }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.h b/jni/libzrtp/sources/zrtp/crypto/skein384.h
deleted file mode 100644
index 61fd64e..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein384 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN384_H
-#define _SKEIN384_H
-
-/**
- * @file skein384.h
- * @brief Functions that provide Skein384 support
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH 48
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein384 digest.
- *
- * This functions takes one data chunk and computes its Skein384 digest. This
- * function creates and deletes an own Skein384 context to perform the Skein384
- * operations.
- *
- * @param data
- * Points to the data chunk.
- * @param data_length
- * Length of the data in bytes
- * @param digest
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data,
- unsigned int data_length,
- unsigned char *digest);
-
-/**
- * Compute Skein384 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein384 digest.
- * This function creates and deletes an own Skein384 context to perform the
- * Skein384 operations.
- *
- * @param data
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param data_length
- * Points to an array of integers that hold the length of each data chunk.
- * @param digest
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data[],
- unsigned int data_length[],
- unsigned char *digest);
-/**
- * Create and initialize a Skein384 context.
- *
- * An application uses this context to hash several data into one Skein384
- * digest. See also skein384Ctx(...) and closeSha384Context(...).
- *
- * @return Returns a pointer to the initialized Skein384 context
- */
-void* createSkein384Context();
-
-/**
- * Compute a digest and close the SHa384 digest.
- *
- * An application uses this function to compute the Skein384 digest and to
- * close the Skein384 context.
- *
- * @param ctx
- * Points to the Skein384 context.
- * @param digest
- * If this pointer is not NULL then it must point to a byte array that
- * is big enough to hold the Skein384 digest (384 bit = 48 Bytes). If this
- * pointer is NULL then the functions does not compute the digest but
- * closes the context only. The context cannot be used anymore.
- */
-void closeSkein384Context(void* ctx,
- unsigned char* digest);
-
-/**
- * Update the Skein384 context with data.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- * Points to the Skein384 context.
- * @param data
- * Points to the data to update the context.
- * @param dataLength
- * The length of the data in bytes.
- */
-void skein384Ctx(void* ctx, unsigned char* data,
- unsigned int dataLength);
-
-/**
- * Update the Skein384 context with several data chunks.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- * Points to the Skein384 context.
- * @param dataChunks
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- * Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein384Ctx(void* ctx, unsigned char* dataChunks[],
- unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
deleted file mode 100644
index b4234e5..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac256.h>
-
-void macSkein256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
- macSkein(key, keyLength, data, dataLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
- *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-
-void macSkein256( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
- macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
- *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void* createMacSkein256Context(uint8_t* key, int32_t keyLength)
-{
- return createSkeinMacContext(key, keyLength, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
- macSkeinCtx(ctx, data, dataLength, mac);
- *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
- macSkeinCtx(ctx, data, dataLength, mac);
- *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void freeMacSkein256Context(void* ctx)
-{
- freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
deleted file mode 100644
index e87a1e1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-/**
- * Methods to compute a Skein256 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN256_H
-#define HMAC_SKEIN256_H
-
-/**
- * @file skeinMac256.h
- * @brief Function that provide Skein256 HMAC support
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH 32
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein256 HMAC.
- *
- * This functions takes one data chunk and computes its Skein256 HMAC.
- *
- * @param key
- * The MAC key.
- * @param key_length
- * Lneght of the MAC key in bytes
- * @param data
- * Points to the data chunk.
- * @param data_length
- * Length of the data in bytes
- * @param mac
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- * Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein256 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein256 HAMAC.
- *
- * @param key
- * The MAC key.
- * @param key_length
- * Lneght of the MAC key in bytes
- * @param data
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param data_length
- * Points to an array of integers that hold the length of each data chunk.
- * @param mac
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- * Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
deleted file mode 100644
index 57c7ad1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH 48
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac384.h>
-
-void macSkein384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
- macSkein(key, keyLength, data, dataLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
- *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-
-void macSkein384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
- macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
- *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void* createMacSkein384Context(uint8_t* key, int32_t keyLength)
-{
- return createSkeinMacContext(key, keyLength, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
- macSkeinCtx(ctx, data, dataLength, mac);
- *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
- macSkeinCtx(ctx, data, dataLength, mac);
- *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void freeMacSkein384Context(void* ctx)
-{
- freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
deleted file mode 100644
index 2065899..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 2013 Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-*/
-
-/**
- * Methods to compute a Skein384 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN384_H
-#define HMAC_SKEIN384_H
-
-/**
- * @file skeinMac384.h
- * @brief Function that provide Skein384 HMAC support
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH 48
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein384 HMAC.
- *
- * This functions takes one data chunk and computes its Skein384 HMAC.
- *
- * @param key
- * The MAC key.
- * @param key_length
- * Lneght of the MAC key in bytes
- * @param data
- * Points to the data chunk.
- * @param data_length
- * Length of the data in bytes
- * @param mac
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- * Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein384 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein384 HAMAC.
- *
- * @param key
- * The MAC key.
- * @param key_length
- * Lneght of the MAC key in bytes
- * @param data
- * Points to an array of pointers that point to the data chunks. A NULL
- * pointer in an array element terminates the data chunks.
- * @param data_length
- * Points to an array of integers that hold the length of each data chunk.
- * @param mac
- * Points to a buffer that receives the computed digest. This
- * buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- * Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
deleted file mode 100644
index d718f24..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- Copyright (C) 2006, 2009 by Werner Dittmann
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you
- * do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/** Copyright (C) 2006, 2009
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <bn.h>
-#include <bnprint.h>
-#include <ec/ec.h>
-#include <ec/ecdh.h>
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
-#include <cryptcommon/aes.h>
-#include <cryptcommon/ZrtpRandom.h>
-
-
-static BigNum bnP2048 = {0};
-static BigNum bnP3072 = {0};
-
-static BigNum bnP2048MinusOne = {0};
-static BigNum bnP3072MinusOne = {0};
-
-static BigNum two = {0};
-
-static uint8_t dhinit = 0;
-
-typedef struct _dhCtx {
- BigNum privKey;
- BigNum pubKey;
- EcCurve curve;
- EcPoint pubPoint;
-} dhCtx;
-
-void randomZRTP(uint8_t *buf, int32_t length)
-{
- ZrtpRandom::getRandomData(buf, length);
-}
-
-static const uint8_t P2048[] =
-{
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
- 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
- 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
- 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
- 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
- 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
- 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
- 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
- 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
- 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
- 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
- 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
- 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
- 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
- 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
- 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
- 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
- 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
- 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
- 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
- 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-static const uint8_t P3072[] =
-{
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
- 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
- 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
- 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
- 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
- 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
- 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
- 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
- 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
- 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
- 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
- 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
- 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
- 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
- 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
- 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
- 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
- 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
- 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
- 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
- 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
- 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
- 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
- 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
- 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
- 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
- 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
- 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
- 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
- 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
- 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
- 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-/* **************
-static const uint8_t P4096[] =
-{
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
-0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
-0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
-0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
-0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
-0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
-0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
-0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
-0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
-0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
-0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
-0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
-0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
-0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
-0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
-0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
-0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
-0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
-0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
-0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
-0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
-0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
-0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
-0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
-0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
-0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
-0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-*************** */
-
-ZrtpDH::ZrtpDH(const char* type) {
-
- uint8_t random[64];
-
- ctx = static_cast<void*>(new dhCtx);
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
- // Well - the algo type is only 4 char thus cast to int32 and compare
- if (*(int32_t*)type == *(int32_t*)dh2k) {
- pkType = DH2K;
- }
- else if (*(int32_t*)type == *(int32_t*)dh3k) {
- pkType = DH3K;
- }
- else if (*(int32_t*)type == *(int32_t*)ec25) {
- pkType = EC25;
- }
- else if (*(int32_t*)type == *(int32_t*)ec38) {
- pkType = EC38;
- }
- else if (*(int32_t*)type == *(int32_t*)e255) {
- pkType = E255;
- }
- else if (*(int32_t*)type == *(int32_t*)e414) {
- pkType = E414;
- }
- else {
- return;
- }
-
- randomZRTP(random, sizeof(random));
-
- if (!dhinit) {
- bnBegin(&two);
- bnSetQ(&two, 2);
-
- bnBegin(&bnP2048);
- bnInsertBigBytes(&bnP2048, P2048, 0, sizeof(P2048));
- bnBegin(&bnP3072);
- bnInsertBigBytes(&bnP3072, P3072, 0, sizeof(P3072));
-
- bnBegin(&bnP2048MinusOne);
- bnCopy(&bnP2048MinusOne, &bnP2048);
- bnSubQ(&bnP2048MinusOne, 1);
-
- bnBegin(&bnP3072MinusOne);
- bnCopy(&bnP3072MinusOne, &bnP3072);
- bnSubQ(&bnP3072MinusOne, 1);
-
- dhinit = 1;
- }
-
- bnBegin(&tmpCtx->privKey);
- INIT_EC_POINT(&tmpCtx->pubPoint);
-
- switch (pkType) {
- case DH2K:
- case DH3K:
- bnInsertBigBytes(&tmpCtx->privKey, random, 0, 256/8);
- break;
-
- case EC25:
- ecGetCurveNistECp(NIST256P, &tmpCtx->curve);
- ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
- break;
-
- case EC38:
- ecGetCurveNistECp(NIST384P, &tmpCtx->curve);
- ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
- break;
-
- case E255:
- ecGetCurvesCurve(Curve25519, &tmpCtx->curve);
- ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
- break;
-
- case E414:
- ecGetCurvesCurve(Curve3617, &tmpCtx->curve);
- ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
- break;
- }
-}
-
-ZrtpDH::~ZrtpDH() {
- if (ctx == NULL)
- return;
-
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
- FREE_EC_POINT(&tmpCtx->pubPoint);
- bnEnd(&tmpCtx->privKey);
-
- switch (pkType) {
- case DH2K:
- case DH3K:
- bnEnd(&tmpCtx->pubKey);
- break;
-
- case EC25:
- case EC38:
- ecFreeCurveNistECp(&tmpCtx->curve);
- break;
-
- case E255:
- case E414:
- ecFreeCurvesCurve(&tmpCtx->curve);
- break;
- }
-}
-
-int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {
-
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
- int32_t length = getDhSize();
-
- BigNum sec;
- if (pkType == DH2K || pkType == DH3K) {
- BigNum pubKeyOther;
- bnBegin(&pubKeyOther);
- bnBegin(&sec);
-
- bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, length);
-
- if (pkType == DH2K) {
- bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP2048);
- }
- else if (pkType == DH3K) {
- bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP3072);
- }
- else {
- return 0;
- }
- bnEnd(&pubKeyOther);
- bnExtractBigBytes(&sec, secret, 0, length);
- bnEnd(&sec);
-
- return length;
- }
-
- if (pkType == EC25 || pkType == EC38 || pkType == E414) {
- int32_t len = getPubKeySize() / 2;
- EcPoint pub;
-
- bnBegin(&sec);
- INIT_EC_POINT(&pub);
- bnSetQ(pub.z, 1); // initialze Z to one, these are affine coords
-
- bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
- bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
-
- /* Generate agreement for responder: sec = pub * privKey */
- ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
- bnExtractBigBytes(&sec, secret, 0, length);
- bnEnd(&sec);
- FREE_EC_POINT(&pub);
-
- return length;
- }
- if (pkType == E255) {
- int32_t len = getPubKeySize();
- EcPoint pub;
-
- bnBegin(&sec);
- INIT_EC_POINT(&pub);
-
- bnInsertLittleBytes(pub.x, pubKeyBytes, 0, len);
-
- /* Generate agreement for responder: sec = pub * privKey */
- ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
- bnExtractLittleBytes(&sec, secret, 0, length);
- bnEnd(&sec);
- FREE_EC_POINT(&pub);
-
- return length;
- }
- return -1;
-}
-
-int32_t ZrtpDH::generatePublicKey()
-{
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
- bnBegin(&tmpCtx->pubKey);
- switch (pkType) {
- case DH2K:
- bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP2048);
- break;
-
- case DH3K:
- bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP3072);
- break;
-
- case EC25:
- case EC38:
- case E255:
- case E414:
- while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))
- ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
- }
- return 0;
-}
-
-int32_t ZrtpDH::getDhSize() const
-{
- switch (pkType) {
- case DH2K:
- return 2048/8;
- break;
- case DH3K:
- return 3072/8;
- break;
-
- case EC25:
- return 32;
- break;
- case EC38:
- return 48;
- break;
-
- case E255:
- return 32;
- break;
- case E414:
- return 52;
- break;
- }
- return 0;
-}
-
-int32_t ZrtpDH::getPubKeySize() const
-{
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
- if (pkType == DH2K || pkType == DH3K)
- return bnBytes(&tmpCtx->pubKey);
-
- if (pkType == EC25 || pkType == EC38 || pkType == E414)
- return bnBytes(tmpCtx->curve.p) * 2; // *2 -> x and y coordinate
-
- if (pkType == E255)
- return bnBytes(tmpCtx->curve.p);
- return 0;
-
-}
-
-int32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const
-{
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
- if (pkType == DH2K || pkType == DH3K) {
- // get len of pub_key, prepend with zeros to DH size
- int size = getPubKeySize();
- int32_t prepend = getDhSize() - size;
- if (prepend > 0) {
- memset(buf, 0, prepend);
- }
- bnExtractBigBytes(&tmpCtx->pubKey, buf + prepend, 0, size);
- return size;
- }
-
- if (pkType == EC25 || pkType == EC38 || pkType == E414) {
- int32_t len = getPubKeySize() / 2;
-
- bnExtractBigBytes(tmpCtx->pubPoint.x, buf, 0, len);
- bnExtractBigBytes(tmpCtx->pubPoint.y, buf+len, 0, len);
- return len * 2;
- }
- if (pkType == E255) {
- int32_t len = getPubKeySize();
- bnExtractLittleBytes(tmpCtx->pubPoint.x, buf, 0, len);
- return len;
- }
- return 0;
-}
-
-int32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const
-{
-
- /* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */
- if (pkType == EC25 || pkType == EC38 || pkType == E414) {
-
- dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
- EcPoint pub;
-
- INIT_EC_POINT(&pub);
- int32_t len = getPubKeySize() / 2;
-
- bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
- bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
-
- return ecCheckPubKey(&tmpCtx->curve, &pub);
- }
-
- if (pkType == E255) {
- return 1;
- }
-
- BigNum pubKeyOther;
- bnBegin(&pubKeyOther);
- bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, getDhSize());
-
- if (pkType == DH2K) {
- if (bnCmp(&bnP2048MinusOne, &pubKeyOther) == 0) {
- return 0;
- }
- }
- else if (pkType == DH3K) {
- if (bnCmp(&bnP3072MinusOne, &pubKeyOther) == 0) {
- return 0;
-
- }
- }
- else {
- return 0;
- }
- if (bnCmpQ(&pubKeyOther, 1) == 0) {
- return 0;
- }
-
- bnEnd(&pubKeyOther);
- return 1;
-}
-
-const char* ZrtpDH::getDHtype()
-{
- switch (pkType) {
- case DH2K:
- return dh2k;
- case DH3K:
- return dh3k;
- case EC25:
- return ec25;
- case EC38:
- return ec38;
- case E255:
- return e255;
- case E414:
- return e414;
- }
- return NULL;
-}
-
-/** EMACS **
- * Local variables:
- * mode: c++
- * c-default-style: ellemtel
- * c-basic-offset: 4
- * End:
- */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
deleted file mode 100644
index 2ba1de6..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <string>
-
-#include "ZIDRecord.h"
-
-#ifndef _ZIDCACHE_H_
-#define _ZIDCACHE_H_
-
-/**
- * @file ZIDCache.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecord for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * Interface for classes that implements a ZID (ZRTP Identifiers) file.
- *
- * The ZID file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class ZIDCache;
-
-__EXPORT ZIDCache* getZidCacheInstance();
-
-
-class __EXPORT ZIDCache {
-
-public:
-
- /**
- * @brief Destructor.
- * Define a virtual destructor to enable cleanup in derived classes.
- */
- virtual ~ZIDCache() {};
-
- /**
- * @brief Open the named ZID file and return a ZID file class.
- *
- * This static function either opens an existing ZID file or
- * creates a new ZID file with the given name. The ZIDCache is a
- * singleton, thus only <em>one</em> ZID file can be open at one
- * time.
- *
- * To open another ZID file you must close the active ZID file
- * first.
- *
- * @param name
- * The name of the ZID file to open or create
- * @return
- * 1 if file could be opened/created, 0 if the ZID instance
- * already has an open file, -1 if open/creation of file failed.
- */
- virtual int open(char *name) =0;
-
- /**
- * @brief Check if ZIDCache has an active (open) file.
- *
- * @return
- * True if ZIDCache has an active file, false otherwise
- */
- virtual bool isOpen() =0;
-
- /**
- * @brief Close the ZID file.
- *
- * Closes the ZID file, and prepares to open a new ZID file.
- */
- virtual void close() =0;
-
- /**
- * @brief Get a ZID record from ZID cache or create a new record.
- *
- * The method tries to read a ZRTP cache record for the ZID.
- * If no matching record exists in the cache the method creates
- * it and fills it with default values.
- *
- * @param zid is the ZRTP id of the peer
- * @return pointer to the ZID record. The call must @c delete the
- * record if it is not longer used.
- */
- virtual ZIDRecord *getRecord(unsigned char *zid) =0;
-
- /**
- * @brief Save a ZID record into the active ZID file.
- *
- * This method saves the content of a ZID record into the ZID file. Before
- * you can save the ZID record you must have performed a getRecord()
- * first.
- *
- * @param zidRecord
- * The ZID record to save.
- * @return
- * 1 on success
- */
- virtual unsigned int saveRecord(ZIDRecord *zidRecord) =0;
-
- /**
- * @brief Get the ZID associated with this ZID file.
- *
- * @return
- * Pointer to the ZID
- */
- virtual const unsigned char* getZid() =0;
-
- /**
- * @brief Get peer name from database
- *
- * This is an optional function.
- *
- * A client may use this function to retrieve a name that was assigned
- * to the peer's ZID.
- *
- * @param peerZid the peer's ZID
- *
- * @param name string that will get the peer's name. The returned name will
- * be truncated to 200 bytes
- *
- * @return length og the name read or 0 if no name was previously stored.
- */
- virtual int32_t getPeerName(const uint8_t *peerZid, std::string *name) =0;
-
- /**
- * @brief Write peer name to database
- *
- * This is an optional function.
- *
- * A client may use this function to write a name in the ZRTP cache database and
- * asign it to the peer's ZID.
- *
- * @param peerZid the peer's ZID
- *
- * @param name the name string
- *
- */
- virtual void putPeerName(const uint8_t *peerZid, const std::string name) =0;
-
- /**
- * @brief Clean the cache.
- *
- * The function drops and re-creates all tables in the database. This removes all stored
- * data. The application must not call this while a ZRTP call is active. Also the application
- * <b>must</b> get the local ZID again.
- *
- */
- virtual void cleanup() =0;
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
deleted file mode 100644
index 7aa6dd0..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#include <libzrtpcpp/ZIDCache.h>
-#include <libzrtpcpp/ZIDRecordDb.h>
-#include <libzrtpcpp/zrtpCacheDbBackend.h>
-
-#ifndef _ZIDCACHEDB_H_
-#define _ZIDCACHEDB_H_
-
-
-/**
- * @file ZIDCacheDb.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecordDb for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * This class implements a ZID (ZRTP Identifiers) file.
- *
- * The interface defintion @c ZIDCache.h contains the method documentation.
- * The ZID cache file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class __EXPORT ZIDCacheDb: public ZIDCache {
-
-private:
-
- void *zidFile;
- unsigned char associatedZid[IDENTIFIER_LEN];
-
- dbCacheOps_t cacheOps;
-
- char errorBuffer[DB_CACHE_ERR_BUFF_SIZE];
-
- void createZIDFile(char* name);
-
-public:
-
- ZIDCacheDb(): zidFile(NULL) {
- getDbCacheOps(&cacheOps);
- };
-
- ~ZIDCacheDb();
-
- int open(char *name);
-
- bool isOpen() { return (zidFile != NULL); };
-
- void close();
-
- ZIDRecord *getRecord(unsigned char *zid);
-
- unsigned int saveRecord(ZIDRecord *zidRecord);
-
- const unsigned char* getZid() { return associatedZid; };
-
- int32_t getPeerName(const uint8_t *peerZid, std::string *name);
-
- void putPeerName(const uint8_t *peerZid, const std::string name);
-
- void cleanup();
-
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
deleted file mode 100644
index 7b264e8..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#include <libzrtpcpp/ZIDCache.h>
-#include <libzrtpcpp/ZIDRecordFile.h>
-
-#ifndef _ZIDCACHEFILE_H_
-#define _ZIDCACHEFILE_H_
-
-
-/**
- * @file ZIDCacheFile.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecord for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * This class implements a ZID (ZRTP Identifiers) file.
- *
- * The interface defintion @c ZIDCache.h contains the method documentation.
- * The ZID cache file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class __EXPORT ZIDCacheFile: public ZIDCache {
-
-private:
-
- FILE* zidFile;
- unsigned char associatedZid[IDENTIFIER_LEN];
-
- void createZIDFile(char* name);
- void checkDoMigration(char* name);
-
-public:
-
- ZIDCacheFile(): zidFile(NULL) {};
-
- ~ZIDCacheFile();
-
- int open(char *name);
-
- bool isOpen() { return (zidFile != NULL); };
-
- void close();
-
- ZIDRecord *getRecord(unsigned char *zid);
-
- unsigned int saveRecord(ZIDRecord *zidRecord);
-
- const unsigned char* getZid() { return associatedZid; };
-
- int32_t getPeerName(const uint8_t *peerZid, std::string *name);
-
- void putPeerName(const uint8_t *peerZid, const std::string name);
-
- // Not implemented for file base cache
- void cleanup() {};
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
deleted file mode 100644
index c46fc24..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZIDRECORD_H_
-#define _ZIDRECORD_H_
-
-#include <stdint.h>
-#include <common/osSpecifics.h>
-/**
- * @file ZIDRecord.h
- * @brief ZID cache record management
- *
- * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
- * to achives its key continuity feature. Please refer to the ZRTP
- * specification to get detailed information about the ZID.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * These length are fixed for ZRTP. See RFC 6189.
- */
-#define IDENTIFIER_LEN 12
-#define RS_LENGTH 32
-
-#if defined(__cplusplus)
-/**
- * Interface for classes that implement a ZID cache record.
- *
- * The ZID cache record holds data about a peer. According to ZRTP specification
- * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data
- * to construct shared secrets.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class __EXPORT ZIDRecord {
-
-public:
- /**
- * @brief Destructor.
- * Define a virtual destructor to enable cleanup in derived classes.
- */
- virtual ~ZIDRecord() {};
-
- /**
- * Set the @c ZID in the record.
- *
- * Set the ZID in this record before calling read or save.
- */
- virtual void setZid(const unsigned char *zid) =0;
-
- /**
- * Set @c valid flag in RS1
- */
- virtual void setRs1Valid() =0;
-
- /**
- * reset @c valid flag in RS1
- */
- virtual void resetRs1Valid() =0;
-
- /**
- * Check @c valid flag in RS1
- */
- virtual bool isRs1Valid() =0;
-
- /**
- * Set @c valid flag in RS2
- */
- virtual void setRs2Valid() =0;
-
- /**
- * Reset @c valid flag in RS2
- */
- virtual void resetRs2Valid() =0;
-
- /**
- * Check @c valid flag in RS2
- */
- virtual bool isRs2Valid() =0;
-
- /**
- * Set MITM key available
- */
- virtual void setMITMKeyAvailable() =0;
-
- /**
- * Reset MITM key available
- */
- virtual void resetMITMKeyAvailable() =0;
-
- /**
- * Check MITM key available is set
- */
- virtual bool isMITMKeyAvailable() =0;
-
- /**
- * Mark this as own ZID record
- */
- virtual void setOwnZIDRecord() =0;
-
- /**
- * Reset own ZID record marker
- */
- virtual void resetOwnZIDRecord() =0;
-
- /**
- * Check own ZID record marker
- */
- virtual bool isOwnZIDRecord() =0;
-
- /**
- * Set SAS for this ZID as verified
- */
- virtual void setSasVerified() =0;
-
- /**
- * Reset SAS for this ZID as verified
- */
- virtual void resetSasVerified() =0;
-
- /**
- * Check if SAS for this ZID was verified
- */
- virtual bool isSasVerified() =0;
-
- /**
- * Return the ZID for this record
- */
- virtual const uint8_t* getIdentifier() =0;
-
- /**
- * Check if RS1 is still valid
- *
- * Returns true if RS1 is still valid, false otherwise.
- *
- * @return
- * Returns true is RS1 is not expired (valid), false otherwise.
- */
- virtual bool isRs1NotExpired() =0;
-
- /**
- * Returns pointer to RS1 data.
- */
- virtual const unsigned char* getRs1() =0;
-
- /**
- * Check if RS2 is still valid
- *
- * Returns true if RS2 is still valid, false otherwise.
- *
- * @return
- * Returns true is RS2 is not expired (valid), false otherwise.
- */
- virtual bool isRs2NotExpired() =0;
-
- /**
- * Returns pointer to RS1 data.
- */
- virtual const unsigned char* getRs2() =0;
-
- /**
- * Sets new RS1 data and associated expiration value.
- *
- * If the expiration value is >0 or -1 the method stores the new
- * RS1. Before it stores the new RS1 it shifts the exiting RS1
- * into RS2 (together with its expiration time). Then it computes
- * the expiration time of the and stores the result together with
- * the new RS1.
- *
- * If the expiration value is -1 then this RS will never expire.
- *
- * If the expiration value is 0 then the expiration value of a
- * stored RS1 is cleared and no new RS1 value is stored. Also RS2
- * is left unchanged.
- *
- * @param data
- * Points to the new RS1 data.
- * @param expire
- * The expiration interval in seconds. Default is -1.
- *
- */
- virtual void setNewRs1(const unsigned char* data, int32_t expire =-1) =0;
-
- /**
- * Set MiTM key data.
- *
- */
- virtual void setMiTMData(const unsigned char* data) =0;
-
- /**
- * Get MiTM key data.
- *
- */
- virtual const unsigned char* getMiTMData() =0;
-};
-#endif /* (__cplusplus) */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
deleted file mode 100644
index 111b4ed..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZIDRECORDDB_H_
-#define _ZIDRECORDDB_H_
-
-
-/**
- * @file ZIDRecordDb.h
- * @brief ZID cache record management
- *
- * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
- * to achives its key continuity feature. Please refer to the ZRTP
- * specification to get detailed information about the ZID.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <libzrtpcpp/ZIDRecord.h>
-
-#define TIME_LENGTH 8 // 64 bit, can hold time on 64 bit systems
-
-/**
- * Internal structure that holds the non-key data of a remote ZID record.
- *
- * The data storage backends use this structure to get or to fill in data
- * to store in or that was read from the data store.
- *
- * Some notes regarding the timestamps: the structure uses 64 bit variables to
- * store a timestamp. The relevant SQL SELECT / UPDATE / INSERT statements and
- * the relevant must take care of this.
- *
- * The methods shall use the standard C time() call to get the current time in
- * seconds since Unix epoch (see time() documentation).
- */
-typedef struct {
- uint8_t identifier[IDENTIFIER_LEN]; /* < the peer's ZID or own ZID */
- uint32_t flags;
- uint8_t rs1[RS_LENGTH];
- int64_t rs1LastUse;
- int64_t rs1Ttl;
- uint8_t rs2[RS_LENGTH];
- int64_t rs2LastUse;
- int64_t rs2Ttl;
- uint8_t mitmKey[RS_LENGTH];
- int64_t mitmLastUse;
- int64_t secureSince;
- uint32_t preshCounter;
-} remoteZidRecord_t;
-
-/*
- * The flag field stores the following bitflags
- */
-static const uint32_t Valid = 0x1;
-static const uint32_t SASVerified = 0x2;
-static const uint32_t RS1Valid = 0x4;
-static const uint32_t RS2Valid = 0x8;
-static const uint32_t MITMKeyAvailable = 0x10;
-static const uint32_t inUse = 0x20;
-
-/**
- * Internal structure that holds the non-key data of a ZID name record.
- *
- * The flags field currently just uses the @c Valid bit.
- *
- * See comment on @c remoteZidRecord_t above.
- */
-typedef struct {
- uint32_t flags;
- char *name;
- int32_t nameLength;
-} zidNameRecord_t;
-
-#if defined(__cplusplus)
-/**
- * This class implements the ZID record.
- *
- * The ZID record holds data about a peer. According to ZRTP specification
- * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data
- * to construct shared secrets.
- * <p>
- * NOTE: ZIDRecordDb has ZIDCacheDb as friend. ZIDCacheDb knows about the private
- * data of ZIDRecord - please keep both classes synchronized.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class __EXPORT ZIDRecordDb: public ZIDRecord {
- friend class ZIDCacheDb;
-
-private:
- remoteZidRecord_t record;
-
- remoteZidRecord_t* getRecordData() {return &record; }
- int getRecordLength() {return sizeof(remoteZidRecord_t); }
-
- bool isValid() { return ((record.flags & Valid) == Valid); }
- void setValid() { record.flags |= Valid; }
-
-public:
- /*
- * @brief The default constructor,
- */
- ZIDRecordDb() {
- memset(&record, 0, sizeof(remoteZidRecord_t));
- }
-
- /**
- * Set the @c ZID in the record.
- *
- * Set the ZID in this record before calling read or save.
- */
- void setZid(const unsigned char *zid) {
- memcpy(record.identifier, zid, IDENTIFIER_LEN);
- }
-
- /**
- * Set @c valid flag in RS1
- */
- void setRs1Valid() { record.flags |= RS1Valid; }
-
- /**
- * reset @c valid flag in RS1
- */
- void resetRs1Valid() { record.flags &= ~RS1Valid; }
-
- /**
- * Check @c valid flag in RS1
- */
- bool isRs1Valid() { return ((record.flags & RS1Valid) == RS1Valid); }
-
- /**
- * Set @c valid flag in RS2
- */
- void setRs2Valid() { record.flags |= RS2Valid; }
-
- /**
- * Reset @c valid flag in RS2
- */
- void resetRs2Valid() { record.flags &= ~RS2Valid; }
-
- /**
- * Check @c valid flag in RS2
- */
- bool isRs2Valid() { return ((record.flags & RS2Valid) == RS2Valid); }
-
- /**
- * Set MITM key available
- */
- void setMITMKeyAvailable() { record.flags |= MITMKeyAvailable; }
-
- /**
- * Reset MITM key available
- */
- void resetMITMKeyAvailable() { record.flags &= ~MITMKeyAvailable; }
-
- /**
- * Check MITM key available is set
- */
- bool isMITMKeyAvailable() { return ((record.flags & MITMKeyAvailable) == MITMKeyAvailable); }
-
- /**
- * Mark this as own ZID record - not used in this DB cache backend
- */
- void setOwnZIDRecord() {}
- /**
- * Reset own ZID record marker
- */
- void resetOwnZIDRecord(){}
-
- /**
- * Check own ZID record marker
- */
- bool isOwnZIDRecord() { return false; } // in this DB cahe implementation a record is always 'remote'
-
- /**
- * Set SAS for this ZID as verified
- */
- void setSasVerified() { record.flags |= SASVerified; }
- /**
- * Reset SAS for this ZID as verified
- */
- void resetSasVerified() { record.flags &= ~SASVerified; }
-
- /**
- * Check if SAS for this ZID was verified
- */
- bool isSasVerified() { return ((record.flags & SASVerified) == SASVerified); }
-
- /**
- * Return the ZID for this record
- */
- const uint8_t* getIdentifier() {return record.identifier; }
-
- /**
- * Check if RS1 is still valid
- *
- * Returns true if RS1 is still valid, false otherwise.
- *
- * @return
- * Returns true is RS1 is not expired (valid), false otherwise.
- */
- bool isRs1NotExpired();
-
- /**
- * Returns pointer to RS1 data.
- */
- const unsigned char* getRs1() { return record.rs1; }
-
- /**
- * Check if RS2 is still valid
- *
- * Returns true if RS2 is still valid, false otherwise.
- *
- * @return
- * Returns true is RS2 is not expired (valid), false otherwise.
- */
- bool isRs2NotExpired();
-
- /**
- * Returns pointer to RS1 data.
- */
- const unsigned char* getRs2() { return record.rs2; }
-
- /**
- * Sets new RS1 data and associated expiration value.
- *
- * If the expiration value is >0 or -1 the method stores the new
- * RS1. Before it stores the new RS1 it shifts the exiting RS1
- * into RS2 (together with its expiration time). Then it computes
- * the expiration time of the and stores the result together with
- * the new RS1.
- *
- * If the expiration value is -1 then this RS will never expire.
- *
- * If the expiration value is 0 then the expiration value of a
- * stored RS1 is cleared and no new RS1 value is stored. Also RS2
- * is left unchanged.
- *
- * @param data
- * Points to the new RS1 data.
- * @param expire
- * The expiration interval in seconds. Default is -1.
- *
- */
- void setNewRs1(const unsigned char* data, int32_t expire =-1);
-
- /**
- * Set MiTM key data.
- *
- */
- void setMiTMData(const unsigned char* data);
-
- /**
- * Get MiTM key data.
- *
- */
- const unsigned char* getMiTMData() {return record.mitmKey; }
-};
-#endif /* (__cplusplus) */
-
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
deleted file mode 100644
index d7d2265..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTPSDESSTREAM_H_
-#define _ZRTPSDESSTREAM_H_
-/**
- * @file ZrtpSdesStream.h
- * @brief The ZRTP main engine
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- *
- * This class implements SDES and provides a simple to use API for applications.
- *
- * This SDES implementation currently supports only two SDES algorithms and it does
- * not support optional parameters such as lifetime or MKI parameters. Also session
- * parameters are not supported. Most applications that use SDES don't use these
- * optional parameters.
- *
- * It is not necessary to explicitly start the SDES stream. The class initiates
- * the SRTP after it created and parsed all necessary SDES crypto strings.
- *
- * Because SDES works together with the signaling protocol, for example SIP, it is
- * important to adhere to a defined flow. The following pseudo code snippet depicts
- * such a flow. Applications shall follow this flow.
- *
- *<pre>
- *
- * Inviter Answerer
- * (Offerer)
- *
- * ZrtpSdesStream inv; ZrtpSdesStream answ;
- *
- * // create/get own SDES data
- * inv.createSdes(...);
- * inv.getCryptoMixAttribute(...)
- *
- * // prepare SIP/SDP offer, send
- * // it to answerer
- * // receive SIP/SDP, get
- * // SDES data, parse/set it
- * answ.setCryptoMixAttribute(...)
- * answ.parseSdes(...)
- *
- * // create/get own SDES data
- * answ.getCryptoMixAttribute(...)
- * answ.createSdes(...)
- *
- * // prepare SIP/SDP answer,
- * // send to offerer
- * // receive SIP/SDP answer, get
- * // SDES data, parse, set mix algo
- * // if availabe
- * inv.setCryptoMixAttribute(...)
- * inv.parseSdes(...)
- *
- * ... ...
- *
- * inv.outgoingRtp(...)
- * answ.incomingRtp(...)
- *
- * answ.outgoingRtp(...)
- * inv.incomingRtp(...)
- *</pre>
- *
- * To use SDES without the new crypto mix feature just do not use the crypto mix functions.
- * An application may always send crypto mix attributes. If the answerer does not support this
- * feature it does not send back a selected algorithm and the offerer cannot set an algorithm.
- * Thus the crypto mix feature is not used.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <common/osSpecifics.h>
-
-class CryptoContext;
-class CryptoContextCtrl;
-
-/*
- * These functions support 256 bit encryption algorithms.
- */
-#define MAX_KEY_LEN 32
-#define MAX_SALT_LEN 14
-#define MAX_DIGEST_LENGTH 64
-
-/**
- * Maximum length of a raw crypto string.
- */
-#define MAX_CRYPT_STRING_LEN 200
-
-class __EXPORT ZrtpSdesStream {
-
-public:
-
- /**
- * Supported SDES crypto suites.
- */
- typedef enum {
- AES_CM_128_HMAC_SHA1_32 = 0,
- AES_CM_128_HMAC_SHA1_80
- } sdesSuites;
-
- /**
- * SDES stream state
- */
- typedef enum {
- STREAM_INITALIZED = 1,
- OUT_PROFILE_READY,
- IN_PROFILE_READY,
- SDES_SRTP_ACTIVE
- } sdesZrtpStates;
-
- typedef enum {
- MIX_NONE = 0,
- MIX_HMAC_SHA,
- MIX_MAC_SKEIN
- } sdesHmacTypeMix;
-
- /**
- * @brief Create and SDES/ZRTP stream.
- *
- * This method creates an SDES stream with capabilities to handle RTP,
- * RTCP, SRTP, and SRTCP packets.
- *
- * @param suite defines which crypto suite to use for this stream. The values are
- * @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32.
- */
- ZrtpSdesStream(const sdesSuites suite =AES_CM_128_HMAC_SHA1_32);
-
- ~ZrtpSdesStream();
-
- /**
- * @brief Close an SDES/ZRTP stream.
- *
- * Close the stream and return allocated memory to the pool.
- */
- void close();
-
- /**
- * @brief Creates an SDES crypto string for the SDES/ZRTP stream.
- *
- * Creates the crypto string that the application can use in the SDP fields of
- * SIP INVITE or SIP 200 OK.
- *
- * An INVITE-ing application shall call this function at the same point when
- * it calls the functions to get the @c zrtp-hash string and shall insert the
- * created crypto string into the SDP.
- *
- * An answering application shall call this function directly @b after it called
- * @c sdesZrtpStreamParseSdes. This usually at the same point when it gets the
- * @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The
- * answering application's SRTP environment is now ready.
- *
- * @param cryptoString output buffer that receives the crypto string in raw
- * format, without the any signaling prefix, for example
- * @c a=crypto:. The function terminates the crypto string
- * with a @c nul byte
- *
- * @param maxLen length of the crypto string buffer. On return it contains the
- * actual length of the crypto string.
- *
- * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
- * set it to @c false.
- *
- * @return @c true if data could be created, @c false otherwise.
- */
- bool createSdes(char *cryptoString, size_t *maxLen, bool sipInvite);
-
- /**
- * @brief Parses an SDES crypto string for the SDES/ZRTP stream.
- *
- * Parses a SDES crypto string that the application received in a SIP INVITE
- * or SIP 200 OK.
- *
- * An INVITE-ing (offerer) application shall call this function right after it received
- * the 200 OK from the answering application and must call this function with the
- * @c sipInvite parameter set to @c true. The offerer's SRTP is now ready for use.
- *
- * The answering application calls this function after it received the INVITE and
- * extracted the crypto string from the SDP and must call this function with the
- * @c sipInvite parameter set to @c false.
- *
- * @param cryptoString the received crypto sting in raw format,
- * without any signaling prefix, for example @c a=crypto:
- *
- * @param length length of the crypto string to parse. If the length is
- * @c zero then the function uses @c strlen to compute
- * the length.
- *
- * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
- * set it to @c false.
- *
- * @return @c true if data could be created, @c false otherwise.
- */
- bool parseSdes(const char *cryptoString, size_t length, bool sipInvite);
-
- /**
- * @brief Get Crypto Mix attribute string
- *
- * The offerer calls this method to get a string of @b all supported crypto mix algorithms
- * and shall send this list to the answerer.
- *
- * The answerer calls this function only @b after it received the crypto mix string and @b after
- * calling @c setCryptoMixAttribute(...). The method returns only one (the selected)
- * crypto mix algorithm and the answerer must send this to the offerer, for example in 200 OK.
- *
- * @param algoNames buffer to store the nul terminated crypto mix algorithm names.
- * The buffer must be long enough to hold at least the name of the mandatory
- * algorithm HMAC-SHA-384.
- *
- * @param length length of buffer
- *
- * @return Length of algorithm names (excluding nul byte) or zero if crypto mix not supported or
- * enabled.
- */
- int getCryptoMixAttribute(char *algoNames, size_t length);
-
- /**
- * @brief Set Crypto Mix attribute string
- *
- * The method checks if it the string contains an supported algorithm and selects one algorithm.
- *
- * The offerer calls this method @b after it received the selected algorithm in the answer.
- *
- * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method.
- *
- * @param algoNames buffer that contains the received crypto mix algorithm names.
- * The buffer must be nul terminated.
- *
- * @return @c false if none of the offered algorithms is supported.
- */
- bool setCryptoMixAttribute(const char *algoNames);
-
- /*
- * ******** Outgoing RTP/RTCP packet handling
- */
- /**
- * @brief Process an outgoing RTP packet
- *
- * This function processes an outgoing RTP packet. Depending on the state
- * the packet is either:
- * - not encrypted if neither SDES nor ZRTP are active or supported by the
- * other client. This is the standard case if the stream was just initialized.
- * - encrypted with SDES provided key data. This is the case if the application
- * called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes
- * functions to properly setup the SDES key data.
- *
- * @param packet the buffer that contains the RTP packet. After processing, the
- * encrypted packet is stored in the same buffer. The buffer must
- * big enough to hold the additional SRTP data, depending on the
- * SRTP profile these are usually 4 - 20 bytes.
- *
- * @param length length of the RTP packet
- *
- * @param newLength to an integer that get the new length of the packet including SRTP data.
- *
- * @return
- * - @c true if encryption is successful, app shall send packet to the recipient.
- * - @c false if there was an error during encryption, don't send the packet.
- */
- bool outgoingRtp(uint8_t *packet, size_t length, size_t *newLength);
-
- /**
- * @brief Process an outgoing RTCP packet
- *
- * This function works in the same way as @c outgoingRtp.
- *
- * @param packet the buffer that contains the RTCP packet. After processing, the
- * encrypted packet is stored in the same buffer. The buffer must
- * big enough to hold the additional SRTP data, depending on the
- * SRTP profile these are usually 8 - 20 bytes.
- *
- * @param length length of the RTP packet
- *
- * @param newLength to an integer that get the new length of the packet including SRTP data.
- *
- * @return
- * - @c true if encryption is successful, app shall send packet to the recipient.
- * - @c false if there was an error during encryption, don't send the packet.
- */
- bool outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength);
-
- /*
- * ******** Incoming SRTP/SRTCP packet handling
- */
- /**
- * @brief Process an incoming RTP or SRTP packet
- *
- * This function processes an incoming RTP/SRTP packet. Depending on the state
- * the packet is either:
- * - not decrypted if SDES is not active or supported by the
- * other client. This is the standard case if the stream was just initialized.
- * - decrypted with SDES provided key data. This is the case if the application
- * called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes
- * functions to properly setup the SDES key data.
- *
- * @param packet the buffer that contains the RTP/SRTP packet. After processing,
- * the decrypted packet is stored in the same buffer.
- *
- * @param length length of the RTP packet
- *
- * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
- *
- * @return
- * - 1: success,
- * - -1: SRTP authentication failed,
- * - -2: SRTP replay check failed
- */
- int incomingRtp(uint8_t *packet, size_t length, size_t *newLength);
-
- /**
- * @brief Process an incoming RTCP or SRTCP packet
- *
- * This function works in the same way as @c incomingRtp.
- *
- * @param packet the buffer that contains the RTCP/SRTCP packet. After processing,
- * the decrypted packet is stored in the same buffer.
- *
- * @param length length of the RTCP packet
- *
- * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
- *
- * @return
- * - 1: success,
- * - -1: SRTCP authentication failed,
- * - -2: SRTCP replay check failed
- */
- int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength);
-
- /**
- * @brief Process an outgoing ZRTP packet.
- *
- * Works like @c outgoingRtp, refer to that documentation.
- *
- * @param packet the buffer that contains the ZRTP packet.
- *
- * @param length length of the ZRTP packet
- *
- * @param newLength to an integer that get the new length of the packet including SRTP data.
- *
- * @return
- * - @c true if encryption is successful, app shall send packet to the recipient.
- * - @c false if there was an error during encryption, don't send the packet.
- */
- bool outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
- /**
- * @brief Process an incoming ZRTP packet
- *
- * Works like @c incomingRtp, refer to that documentation.
- *
- * @param packet the buffer that contains the ZRTP/SRTP packet. After processing,
- * the decrypted packet is stored in the same buffer.
- *
- * @param length length of the RTP packet
- *
- * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
- *
- * @return
- * - 1: success,
- * - -1: SRTP authentication failed,
- * - -2: SRTP replay check failed
- */
- int incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
- /**
- * @brief Return state of SDES stream.
- *
- * @return state of stream.
- */
- sdesZrtpStates getState() {return state;}
-
- /**
- * @brief Return SDES crypto mixer HMAC type.
- *
- * @return HMAC type
- */
- sdesHmacTypeMix getHmacTypeMix() {return cryptoMixHashType;}
-
- /**
- * @brief Return name of active cipher algorithm.
- *
- * @return point to name of cipher algorithm.
- */
- const char* getCipher();
-
- /**
- * @brief Return name of active SRTP authentication algorithm.
- *
- * @return point to name of authentication algorithm.
- */
- const char* getAuthAlgo();
-
-
- /*
- * ******** Lower layer functions
- */
-private:
- /**
- * @brief Create an SRTP crypto context and the according SDES crypto string.
- *
- * This lower layer method creates an SDES crypto string. It selects a valid
- * crypto suite, generates the key and salt data, converts these into base 64
- * and returns the crypto string in raw format without any signaling prefixes.
- *
- * The output string has the following format:
- * @verbatim
- * 1 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj
- * @endverbatim
- *
- * Applications usually don't use this method directly. Applications shall
- * use the SDES stream functions.
- *
- * Depending on the crypto suite the overall length of the crypto string
- * is variable. For a normal AES_128_CM suite the minumum lenth is 73
- * characters, a AES_256_CM suite results in 97 characters (not counting
- * any signaling prefixes).
- *
- * @param cryptoString points to a char output buffer that receives the
- * crypto string in the raw format, without the any
- * signaling prefix, for example @c a=crypto: in case
- * of SDP signaling. The function terminates the
- * crypto string with a @c nul byte
- *
- * @param maxLen points to an integer. On input this integer specifies the
- * length of the output buffer. If @c maxLen is smaller than
- * the resulting crypto string the function returns an error
- * conde. On return the functions sets @c maxLen to the
- * actual length of the resultig crypto string.
- *
- * @param tag the value of the @c tag field in the crypto string. The
- * answerer must use this input to make sure that the tag value
- * in the answer matches the value in the offer. See RFC 4568,
- * section 5.1.2.
- * If the tag value is @c -1 the function sets the tag to @c 1.
- *
- * @return @c true if data could be created, @c false
- * otherwise.
- */
- bool createSdesProfile(char *cryptoString, size_t *maxLen);
-
- /**
- * @brief Parse and check an offered SDES crypto string and create SRTP crypto context.
- *
- * The method parses an offered SDES crypto string and checks if it is
- * valid. Next it checks if the string contains a supported crypto suite
- * and if the key and salt lengths match the selected crypto suite.
- *
- * Applications usually don't use this method directly. Applications shall
- * use the SDES stream functions.
- *
- * @b NOTE: This function does not support the optional parameters lifetime,
- * MKI, and session parameters. While it can parse liftime and MKI theiy are
- * not evaluated and used. If these parameters are used in the input crypto
- * string the function return @c false.
- *
- * @param cryptoString points to the crypto sting in raw format,
- * without any signaling prefix, for example @c a=crypto: in case of
- * SDP signaling.
- *
- * @param length length of the crypto string to parse. If the length is
- * @c zero then the function uses @c strlen to compute the length.
- *
- * @param parsedSuite the function sets this to the @c sdesSuites enumerator of
- * the parsed crypto suite. The answerer shall use this as input to
- * @c createSdesProfile to make sure that it creates the same crypto suite.
- * See RFC 4568, section 5.1.2
- *
- * @param tag the function sets this to the @c tag value of the parsed crypto
- * string. The answerer must use this as input to @c createSdesProfile
- * to make sure that it creates the correct tag in the crypto string.
- * See RFC 4568, section 5.1.2
- *
- * @return @c true if checks were ok, @c false
- * otherwise.
- */
- bool parseCreateSdesProfile(const char *cryptoString, size_t length, sdesSuites *parsedSuite, int32_t *tag);
-
- /**
- * @brief Create the SRTP contexts after all SDES creation and parsing is done.
- *
- * @param sipInvite if this is set to @c true (not zero) then the method
- * computes the key data for the inviting SIP application (offerer) and
- * for the answerer otherwise.
- */
- void createSrtpContexts(bool sipInvite);
-
- /**
- * @brief Compute the mixed keys if SDES mixing attribute is set.
- *
- * The method takes the parsed or created SDES key material and computes the mixed keys and salt.
- * It replaces the existing key material with the new data.
- *
- * @param sipInvite if this is set to @c true (not zero) then the method
- * computes the key data for the inviting SIP application (offerer) and
- * for the answerer otherwise.
- */
- void computeMixedKeys(bool sipInvite);
-
-
- sdesZrtpStates state;
- sdesSuites suite;
- int32_t tag;
- CryptoContext *recvSrtp; //!< The SRTP context for this stream
- CryptoContextCtrl *recvSrtcp; //!< The SRTCP context for this stream
- CryptoContext *sendSrtp; //!< The SRTP context for this stream
- CryptoContextCtrl *sendSrtcp; //!< The SRTCP context for this stream
- uint32_t srtcpIndex; //!< the local SRTCP index
-
- CryptoContext *recvZrtpTunnel; //!< The SRTP context for sender ZRTP tunnel
- CryptoContext *sendZrtpTunnel; //!< The SRTP context for receiver ZRTP tunnel
-
- int32_t cryptoMixHashLength;
- sdesHmacTypeMix cryptoMixHashType;
-
- // Variables for crypto that this client creates and sends to the other client, filled during SDES create
- uint8_t localKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4]; //!< Some buffer for key and salt, multiple of 4
- int localKeyLenBytes;
- int localSaltLenBytes;
- int localCipher;
- int localAuthn;
- int localAuthKeyLen;
- int localTagLength;
-
- // Variables for crypto that this client receives from the other client, filled during SDES parse
- uint8_t remoteKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4]; //!< Some buffer for key and salt, multiple of 4
- int remoteKeyLenBytes;
- int remoteSaltLenBytes;
- int remoteCipher;
- int remoteAuthn;
- int remoteAuthKeyLen;
- int remoteTagLength;
-};
-#endif
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h
deleted file mode 100644
index f53f1ad..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-cdecode.h - c header for a base64 decoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CDECODE_H
-#define BASE64_CDECODE_H
-
-#include <stdint.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef enum
-{
- step_a, step_b, step_c, step_d
-} base64_decodestep;
-
-typedef struct
-{
- base64_decodestep step;
- char plainchar;
-} base64_decodestate;
-
-void base64_init_decodestate(base64_decodestate* state_in);
-
-int base64_decode_value(char value_in);
-
-int base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* BASE64_CDECODE_H */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h
deleted file mode 100644
index f054392..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-cencode.h - c header for a base64 encoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CENCODE_H
-#define BASE64_CENCODE_H
-
-#include <stdint.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef enum
-{
- step_A, step_B, step_C
-} base64_encodestep;
-
-typedef struct
-{
- base64_encodestep step;
- char result;
- int stepcount;
- int lineLength;
-} base64_encodestate;
-
-void base64_init_encodestate(base64_encodestate* state_in, int lineLength);
-
-char base64_encode_value(const int8_t value_in);
-
-int base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
-
-int base64_encode_blockend(char *code_out, base64_encodestate* state_in);
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* BASE64_CENCODE_H */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
deleted file mode 100644
index 8f33462..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- Copyright (C) 2006-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTP_CACHE_DB_BACKEND_H_
-#define _ZRTP_CACHE_DB_BACKEND_H_
-
-#include <libzrtpcpp/ZIDRecordDb.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define DB_CACHE_ERR_BUFF_SIZE 1000
-
-/**
- * Set of accessible operations of database ZRTP cache implementaion.
- *
- * The only public method of the database ZRTP implementation is
- * getDbCacheOps(...) that fills in this call structure. This mechanism
- * decouples the database implementations from libzrtp and possible other
- * clients.
- *
- * Some implementation notes:
- * <ul>
- * <li> All data storage methods return 0 (zero) if the call was successful.
- * </li>
-
- * <li> The @c errString parameter points to a buffer of at least @c
- * DB_CACHE_ERR_BUFF_SIZE character. In case of an error methods shall
- * store detailed, human readable information in this buffer. Use @c
- * snprintf or similar functions to format the data. If this parameter
- * is @c NULL then methods must not return an error string.
- *</li>
- * <li> The methods cast the @c void to the type they need. Be aware that the
- * open functions requires a pointer to a pointer.
- * </li>
- * </ul>
- *
- *
- *
- */
-typedef struct {
- /**
- * @brief Open the cache.
- *
- * @param name String that identifies the database or data storage.
- *
- * @param pdb Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*openCache)(const char* name, void **pdb, char *errString);
-
- /**
- * Close the cache.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- */
- int (*closeCache)(void *db);
-
- /**
- * @brief Read a local ZID from the database.
- *
- * The cache database may implement methods to generate and store local
- * ZRTP identifiers (ZID) and optionally link them with account
- * information. The account information data is the key to the request
- * local ZID. If the application does not provide account information data
- * the method implmentation shall use a standard predfined string that
- * does not collide with usual account information.
- *
- * The SQLite backend uses the string @c "_STANDARD_" in this case and
- * sets a specific type field.
- *
- * The first call to this method with a specific account information
- * generates a ZID, stores it in the database usind the account
- * information as key, and returns the ZID to the application. Any
- * subsequent call with the same account information return the same local
- * ZID.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The method stores the local ZID in this
- * buffer.
- *
- * @param accountInfo Pointer to an account information string or @c NULL
- * if explicit account information is not required.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*readLocalZid)(void *db, uint8_t *localZid, const char *accountInfo, char *errString);
-
- /**
- * @brief Read a remote ZID data structure.
- *
- * The method uses @c remoteZid and @c localZid as keys to read the remote
- * ZID record. If a record does not exist in the database the method
- * clears the @c flags field in the @c remoteZidRecord_t structure and
- * returns without error. The application must check the flags if the
- * method found a valid record.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
- * fills this structure with data it read from the database.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*readRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
- remoteZidRecord_t *remZid, char* errString);
- /**
- * @brief Update an existing remote ZID data structure.
- *
- * The method uses @c remoteZid and @c localZid as keys to update an
- * existing remote ZID record.
- *
- * @b NOTE: application must use this methods only if
- * @c readRemoteZidRecord (see above) returned a @b valid record. If
- * @c readRemoteZidRecord returned an invalid record then no such
- * record exists in the database and the application must use the
- * @c insertRemoteZidRecord (see below).
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
- * gets data from this structure and stores it in the
- * database.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*updateRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
- const remoteZidRecord_t *remZid, char* errString);
- /**
- * @brief Insert a new remote ZID data structure.
- *
- * The method uses @c remoteZid and @c localZid as keys to insert a new
- * remote ZID record.
- *
- * @b NOTE: application must use this methods only if @c
- * readRemoteZidRecord (see above) returned an @b invalid
- * record. Refer to note.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
- * gets data from this structure and stores it in the
- * database.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*insertRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid,
- const remoteZidRecord_t *remZid, char* errString);
-
- /**
- * @brief Read a remote ZID name.
- *
- * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys
- * to read the remote ZID name. If a record does not exist in the database
- * the method clears the @c flags field in the @c zidNameRecord_t structure and
- * returns without error. The application must check the flags if the
- * method found a valid record.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param accountInfo Pointer to an account information string or @c NULL
- * if explicit account information is not required.
- *
- * @param zidName Pointer to the @c zidNameRecord_t structure. The method
- * returns the data in this structure.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*readZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
- /**
- * @brief Update an existing remote ZID data structure.
- *
- * The method uses @c remoteZid and @c localZid as keys to update an
- * existing remote ZID record.
- *
- * @b NOTE: application must use this methods only if
- * @c readZidName (see above) returned a @b valid record. If
- * @c readZidName returned an invalid record then no such
- * record exists in the database and the application must use the
- * @c insertZidNameRecord (see below).
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param accountInfo Pointer to an account information string or @c NULL
- * if explicit account information is not required.
- *
- * @param zidName Pointer to the @c zidNameRecord_t structure. The method
- * gets data from this structure and stores it in the
- * database.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*updateZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
- /**
- * @brief Insert a new ZID name record.
- *
- * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys to
- * insert a new ZID name record.
- *
- * @b NOTE: application must use this methods only if @c readZidName
- * (see above) returned an @b invalid record.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the local ZID.
- *
- * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
- * uint8_t bytes. The buffer must contain the remote ZID.
- *
- * @param accountInfo Pointer to an account information string or @c NULL
- * if explicit account information is not required.
- *
- * @param zidName Pointer to the @c zidNameRecord_t structure. The method
- * gets data from this structure and stores it in the
- * database.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*insertZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
-
- /**
- * @brief Clean the cache.
- *
- * The function drops and re-creates all tables in the database. This removes all stored
- * data. The application must not call this while a ZRTP call is active. Also the application
- * <b>must</b> get the local ZID again.
- *
- * @param db Pointer to an internal structure that the database
- * implementation requires.
- *
- * @param errString Pointer to a character buffer, see implementation
- * notes above.
- */
- int (*cleanCache)(void *db, char* errString);
-} dbCacheOps_t;
-
-void getDbCacheOps(dbCacheOps_t *ops);
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _ZRTP_CACHE_DB_BACKEND_H_*/
diff --git a/jni/libzrtp/sources/zrtp/zrtpB64Decode.c b/jni/libzrtp/sources/zrtp/zrtpB64Decode.c
deleted file mode 100644
index d0fb69e..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpB64Decode.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * cdecoder.c - c source to a base64 decoding algorithm implementation
- *
- * This is part of the libb64 project, and has been placed in the public domain.
- * For details, see http://sourceforge.net/projects/libb64
- */
-
-#include <libzrtpcpp/zrtpB64Decode.h>
-
-int base64_decode_value(char value_in)
-{
- static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
- static const char decoding_size = sizeof(decoding);
- value_in -= 43;
- if (value_in < 0 || value_in > decoding_size) return -1;
- return decoding[(int)value_in];
-}
-
-void base64_init_decodestate(base64_decodestate* state_in)
-{
- state_in->step = step_a;
- state_in->plainchar = 0;
-}
-
-int base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in)
-{
- const char* codechar = code_in;
- uint8_t *plainchar = plaintext_out;
- char fragment;
-
- *plainchar = state_in->plainchar;
-
- switch (state_in->step)
- {
- while (1)
- {
- case step_a:
- do {
- if (codechar == code_in+length_in)
- {
- state_in->step = step_a;
- state_in->plainchar = *plainchar;
- return plainchar - plaintext_out;
- }
- fragment = (char)base64_decode_value(*codechar++);
- } while (fragment < 0);
- *plainchar = (fragment & 0x03f) << 2;
- case step_b:
- do {
- if (codechar == code_in+length_in)
- {
- state_in->step = step_b;
- state_in->plainchar = *plainchar;
- return plainchar - plaintext_out;
- }
- fragment = (char)base64_decode_value(*codechar++);
- } while (fragment < 0);
- *plainchar++ |= (fragment & 0x030) >> 4;
- *plainchar = (fragment & 0x00f) << 4;
- case step_c:
- do {
- if (codechar == code_in+length_in)
- {
- state_in->step = step_c;
- state_in->plainchar = *plainchar;
- return plainchar - plaintext_out;
- }
- fragment = (char)base64_decode_value(*codechar++);
- } while (fragment < 0);
- *plainchar++ |= (fragment & 0x03c) >> 2;
- *plainchar = (fragment & 0x003) << 6;
- case step_d:
- do {
- if (codechar == code_in+length_in)
- {
- state_in->step = step_d;
- state_in->plainchar = *plainchar;
- return plainchar - plaintext_out;
- }
- fragment = (char)base64_decode_value(*codechar++);
- } while (fragment < 0);
- *plainchar++ |= (fragment & 0x03f);
- }
- }
- /* control should not reach here */
- return plainchar - plaintext_out;
-}
-
diff --git a/jni/libzrtp/sources/zrtp/zrtpB64Encode.c b/jni/libzrtp/sources/zrtp/zrtpB64Encode.c
deleted file mode 100644
index 241e3c5..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpB64Encode.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-cencoder.c - c source to a base64 encoding algorithm implementation
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#include <libzrtpcpp/zrtpB64Encode.h>
-
-const int CHARS_PER_LINE = 72;
-
-void base64_init_encodestate(base64_encodestate* state_in, int lineLength)
-{
- state_in->step = step_A;
- state_in->result = 0;
- state_in->stepcount = 0;
- if (lineLength < 0)
- state_in->lineLength = CHARS_PER_LINE / 4;
- else
- state_in->lineLength = (lineLength+3) / 4;
-}
-
-char base64_encode_value(const int8_t value_in)
-{
- static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- if (value_in > 63) return '=';
- return encoding[(int)value_in];
-}
-
-int base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
-{
- const uint8_t *plainchar = plaintext_in;
- const uint8_t *const plaintextend = plaintext_in + length_in;
- char* codechar = code_out;
- char result;
- char fragment;
-
- result = state_in->result;
-
- switch (state_in->step)
- {
- while (1)
- {
- case step_A:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_A;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result = (fragment & 0x0fc) >> 2;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x003) << 4;
- case step_B:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_B;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result |= (fragment & 0x0f0) >> 4;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x00f) << 2;
- case step_C:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_C;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result |= (fragment & 0x0c0) >> 6;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x03f) >> 0;
- *codechar++ = base64_encode_value(result);
-
- if (state_in->lineLength > 0) {
- state_in->stepcount++;
- if (state_in->stepcount == state_in->lineLength)
- {
- *codechar++ = '\n';
- state_in->stepcount = 0;
- }
- }
- }
- }
- /* control should not reach here */
- return codechar - code_out;
-}
-
-int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
-{
- char* codechar = code_out;
-
- switch (state_in->step)
- {
- case step_B:
- *codechar++ = base64_encode_value(state_in->result);
- *codechar++ = '=';
- *codechar++ = '=';
- break;
- case step_C:
- *codechar++ = base64_encode_value(state_in->result);
- *codechar++ = '=';
- break;
- case step_A:
- break;
- }
- if (state_in->lineLength > 0)
- *codechar++ = '\n';
-
- return codechar - code_out;
-}
-
diff --git a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
deleted file mode 100644
index 7dc9cdf..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- Copyright (C) 2012-2013 Werner Dittmann
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <time.h>
-#include <sqlite3.h>
-
-#include <crypto/zrtpDH.h>
-
-#include <libzrtpcpp/zrtpB64Encode.h>
-#include <libzrtpcpp/zrtpB64Decode.h>
-
-#include <libzrtpcpp/zrtpCacheDbBackend.h>
-
-/* Some ported SQLite3 libs do not support the _v2 variants */
-#define SQLITE_USE_V2
-
-#ifdef SQLITE_USE_V2
-#define SQLITE_PREPARE sqlite3_prepare_v2
-#else
-#define SQLITE_PREPARE sqlite3_prepare
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-#ifdef TRANSACTIONS
-static const char *beginTransactionSql = "BEGIN TRANSACTION;";
-static const char *commitTransactionSql = "COMMIT;";
-#endif
-
-/*
- * The database backend uses the following definitions if it implements the localZid storage.
- */
-
-/* The type field in zrtpIdOwn stores the following values */
-static const int32_t localZidStandard = 1; /* this local ZID is not tied to a specific account */
-static const int32_t localZidWithAccount = 2;
-
-/* Default data for account info if none specified */
-static const char *defaultAccountString = "_STANDARD_";
-
-
-/* *****************************************************************************
- * The SQLite master table.
- *
- * Used to check if we have valid ZRTP cache tables.
- */
-static char *lookupTables = "SELECT name FROM sqlite_master WHERE type='table' AND name='zrtpIdOwn';";
-
-
-/* *****************************************************************************
- * SQL statements to process the zrtpIdOwn table.
- */
-static const char *dropZrtpIdOwn = "DROP TABLE zrtpIdOwn;";
-
-/* SQLite doesn't care about the VARCHAR length. */
-static char *createZrtpIdOwn = "CREATE TABLE zrtpIdOwn(localZid CHAR(18), type INTEGER, accountInfo VARCHAR(1000));";
-
-static char *selectZrtpIdOwn = "SELECT localZid FROM zrtpIdOwn WHERE type = ?1 AND accountInfo = ?2;";
-static char *insertZrtpIdOwn = "INSERT INTO zrtpIdOwn (localZid, type, accountInfo) VALUES (?1, ?2, ?3);";
-
-
-/* *****************************************************************************
- * SQL statements to process the remoteId table.
- */
-static const char *dropZrtpIdRemote = "DROP TABLE zrtpIdRemote;";
-
-static const char *createZrtpIdRemote =
- "CREATE TABLE zrtpIdRemote "
- "(remoteZid CHAR(16), localZid CHAR(16), flags INTEGER,"
- "rs1 BLOB(32), rs1LastUsed TIMESTAMP, rs1TimeToLive TIMESTAMP,"
- "rs2 BLOB(32), rs2LastUsed TIMESTAMP, rs2TimeToLive TIMESTAMP,"
- "mitmKey BLOB(32), mitmLastUsed TIMESTAMP, secureSince TIMESTAMP, preshCounter INTEGER);";
-
-static const char *selectZrtpIdRemoteAll =
- "SELECT flags,"
- "rs1, strftime('%s', rs1LastUsed, 'unixepoch'), strftime('%s', rs1TimeToLive, 'unixepoch'),"
- "rs2, strftime('%s', rs2LastUsed, 'unixepoch'), strftime('%s', rs2TimeToLive, 'unixepoch'),"
- "mitmKey, strftime('%s', mitmLastUsed, 'unixepoch'), strftime('%s', secureSince, 'unixepoch'),"
- "preshCounter "
- "FROM zrtpIdRemote WHERE remoteZid=?1 AND localZid=?2;";
-
-static const char *insertZrtpIdRemote =
- "INSERT INTO zrtpIdRemote "
- "(remoteZid, localZid, flags,"
- "rs1, rs1LastUsed, rs1TimeToLive,"
- "rs2, rs2LastUsed, rs2TimeToLive,"
- "mitmKey, mitmLastUsed, secureSince, preshCounter)"
- "VALUES"
- "(?1, ?12, ?2,"
- "?3, strftime('%s', ?4, 'unixepoch'), strftime('%s', ?5, 'unixepoch'),"
- "?6, strftime('%s', ?7, 'unixepoch'), strftime('%s', ?8, 'unixepoch'),"
- "?9, strftime('%s', ?10, 'unixepoch'), strftime('%s', ?11, 'unixepoch'), ?13);";
-
-static const char *updateZrtpIdRemote =
- "UPDATE zrtpIdRemote SET "
- "flags=?2,"
- "rs1=?3, rs1LastUsed=strftime('%s', ?4, 'unixepoch'), rs1TimeToLive=strftime('%s', ?5, 'unixepoch'),"
- "rs2=?6, rs2LastUsed=strftime('%s', ?7, 'unixepoch'), rs2TimeToLive=strftime('%s', ?8, 'unixepoch'),"
- "mitmKey=?9, mitmLastUsed=strftime('%s', ?10, 'unixepoch'),"
- "secureSince=strftime('%s', ?11, 'unixepoch'), preshCounter=?13 "
- "WHERE remoteZid=?1 AND localZid=?12;";
-
-
-/* *****************************************************************************
- * SQL statements to process the name table.
- *
- * The name tables holds free format information and binds it to the combination
- * of local, remote ZIDs and an optional account information.
- */
-static const char *dropZrtpNames = "DROP TABLE zrtpNames;";
-
-static const char *createZrtpNames =
- "CREATE TABLE zrtpNames "
- "(remoteZid CHAR(16), localZid CHAR(16), flags INTEGER, "
- "lastUpdate TIMESTAMP, accountInfo VARCHAR(1000), name VARCHAR(1000));";
-
-static const char *selectZrtpNames =
- "SELECT flags, strftime('%s', lastUpdate, 'unixepoch'), name "
- "FROM zrtpNames "
- "WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;";
-
-static const char *insertZrtpNames =
- "INSERT INTO zrtpNames "
- "(remoteZid, localZid, flags, lastUpdate, accountInfo, name)"
- "VALUES"
- "(?1, ?2, ?4, strftime('%s', ?5, 'unixepoch'), ?3, ?6);";
-
-static const char *updateZrtpNames =
- "UPDATE zrtpNames SET "
- "flags=?4,"
- "lastUpdate=strftime('%s', ?5, 'unixepoch'), name=?6 "
- "WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;";
-
-
-/* *****************************************************************************
- * A few helping macros.
- * These macros require some names/patterns in the methods that use these
- * macros:
- *
- * ERRMSG requires:
- * - a variable with name "db" is the pointer to sqlite3
- * - a char* with name "errString" points to a buffer of at least SQL_CACHE_ERR_BUFF_SIZE chars
- *
- * SQLITE_CHK requires:
- * - a cleanup label, the macro goes to that label in case of error
- * - an integer (int) variable with name "rc" that stores return codes from sqlite
- * - ERRMSG
- */
-#define ERRMSG {if (errString) snprintf(errString, (size_t)DB_CACHE_ERR_BUFF_SIZE, \
- "SQLite3 error: %s, line: %d, error message: %s\n", __FILE__, __LINE__, sqlite3_errmsg(db));}
-#define SQLITE_CHK(func) { \
- rc = (func); \
- if(rc != SQLITE_OK) { \
- ERRMSG; \
- goto cleanup; \
- } \
- }
-
-static int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)
-{
- base64_encodestate _state;
- int codelength;
-
- base64_init_encodestate(&_state, 0);
- codelength = base64_encode_block(binData, binLength, b64Data, &_state);
- codelength += base64_encode_blockend(b64Data+codelength, &_state);
-
- return codelength;
-}
-
-static int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)
-{
- base64_decodestate _state;
- int codelength;
-
- base64_init_decodestate(&_state);
- codelength = base64_decode_block(b64Data, b64length, binData, &_state);
- return codelength;
-}
-
-#ifdef TRANSACTIONS
-static int beginTransaction(sqlite3 *db, char* errString)
-{
- sqlite3_stmt *stmt;
- int rc;
-
- SQLITE_CHK(SQLITE_PREPARE(db, beginTransactionSql, strlen(beginTransactionSql)+1, &stmt, NULL));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-static int commitTransaction(sqlite3 *db, char* errString)
-{
- sqlite3_stmt *stmt;
- int rc;
-
- SQLITE_CHK(SQLITE_PREPARE(db, commitTransactionSql, strlen(commitTransactionSql)+1, &stmt, NULL));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-#endif
-
-/**
- * Initialize remote ZID and remote name tables.
- *
- * First drop the remote ZID and remote name tables and create them again.
- * All information regarding remote peers is lost.
- */
-static int initializeRemoteTables(sqlite3 *db, char* errString)
-{
- sqlite3_stmt * stmt;
- int rc;
-
- /* First drop them, just to be on the save side
- * Ignore errors, there is nothing to drop on empty DB. If ZrtpIdOwn was
- * deleted using DB admin command then we need to drop the remote id table
- * and names also to have a clean state.
- */
- rc = SQLITE_PREPARE(db, dropZrtpIdRemote, strlen(dropZrtpIdRemote)+1, &stmt, NULL);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
-
- rc = SQLITE_PREPARE(db, dropZrtpNames, strlen(dropZrtpNames)+1, &stmt, NULL);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
-
- SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdRemote, strlen(createZrtpIdRemote)+1, &stmt, NULL));
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- SQLITE_CHK(SQLITE_PREPARE(db, createZrtpNames, strlen(createZrtpNames)+1, &stmt, NULL));
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return 0;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-
-}
-/**
- * Create ZRTP cache tables in database.
- *
- * openCache calls this function if it cannot find the table zrtpId_own. This indicates
- * that no ZRTP cache tables are available in the database.
- */
-static int createTables(sqlite3 *db, char* errString)
-{
- sqlite3_stmt * stmt;
- int rc;
-
- /* no ZRTP cache tables were found - create them, first the OwnId table */
- SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdOwn, strlen(createZrtpIdOwn)+1, &stmt, NULL));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return initializeRemoteTables(db, errString);
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-static int insertRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const remoteZidRecord_t *remZid, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc = 0;
-
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- /* Get B64 code for remoteZid first */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid now */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdRemote, strlen(insertZrtpIdRemote)+1, &stmt, NULL));
-
- /* For *_bind_* methods: column index starts with 1 (one), not zero */
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int(stmt, 2, remZid->flags));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 4, remZid->rs1LastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 5, remZid->rs1Ttl));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 7, remZid->rs2LastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 8, remZid->rs2Ttl));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));
- SQLITE_CHK(sqlite3_bind_int(stmt, 13, remZid->preshCounter));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-
-}
-
-static int updateRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const remoteZidRecord_t *remZid, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc;
-
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- /* Get B64 code for remoteZid first */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid now */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpIdRemote, strlen(updateZrtpIdRemote)+1, &stmt, NULL));
-
- /* For *_bind_* methods: column index starts with 1 (one), not zero */
- /* Select for update with the following keys */
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-
- /* Update the following values */
- SQLITE_CHK(sqlite3_bind_int(stmt, 2, remZid->flags));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 4, remZid->rs1LastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 5, remZid->rs1Ttl));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 7, remZid->rs2LastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 8, remZid->rs2Ttl));
- SQLITE_CHK(sqlite3_bind_blob(stmt, 9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));
- SQLITE_CHK(sqlite3_bind_int(stmt, 13, remZid->preshCounter));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-static int readRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- remoteZidRecord_t *remZid, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc;
- int found = 0;
-
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- /* Get B64 code for remoteZid */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdRemoteAll, strlen(selectZrtpIdRemoteAll)+1, &stmt, NULL));
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-
- /* Getting data from result set: column index starts with 0 (zero), not one */
- while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
- remZid->flags = sqlite3_column_int(stmt, 0);
- memcpy(remZid->rs1, sqlite3_column_blob(stmt, 1), RS_LENGTH);
- remZid->rs1LastUse = sqlite3_column_int64(stmt, 2);
- remZid->rs1Ttl = sqlite3_column_int64(stmt, 3);
- memcpy(remZid->rs2, sqlite3_column_blob(stmt, 4), RS_LENGTH);
- remZid->rs2LastUse = sqlite3_column_int64(stmt, 5);
- remZid->rs2Ttl = sqlite3_column_int64(stmt, 6);
- memcpy(remZid->mitmKey, sqlite3_column_blob(stmt, 7), RS_LENGTH);
- remZid->mitmLastUse = sqlite3_column_int64(stmt, 8);
- remZid->secureSince = sqlite3_column_int64(stmt, 9);
- remZid->preshCounter = sqlite3_column_int(stmt, 10);
- found++;
- }
- sqlite3_finalize(stmt);
-
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- if (found == 0) {
- remZid->flags = 0;
- }
- else if (found > 1) {
- if (errString)
- snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, "ZRTP cache inconsistent. More than one remote ZID found: %d\n", found);
- return 1;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-
-static int readLocalZid(void *vdb, uint8_t *localZid, const char *accountInfo, char *errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- char *zidBase64Text;
- int rc = 0;
- int found = 0;
- int type = localZidWithAccount;
-
- if (accountInfo == NULL || !strcmp(accountInfo, defaultAccountString)) {
- accountInfo = defaultAccountString;
- type = localZidStandard;
- }
-
- /* Find a localZid record for this combination */
- SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdOwn, strlen(selectZrtpIdOwn)+1, &stmt, NULL));
-
- SQLITE_CHK(sqlite3_bind_int(stmt, 1, type));
- SQLITE_CHK(sqlite3_bind_text(stmt, 2, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
- /* Loop over result set and count it. However, use only the localZid of first row */
- while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
- if (found == 0) {
- zidBase64Text = (char *)sqlite3_column_text(stmt, 0);
- b64Decode(zidBase64Text, strlen(zidBase64Text), localZid, IDENTIFIER_LEN);
- }
- found++;
- }
- sqlite3_finalize(stmt);
-
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- /* No matching record found, create new local ZID for this combination and store in DB */
- if (found == 0) {
- char b64zid[IDENTIFIER_LEN+IDENTIFIER_LEN] = {0};
- int b64len = 0;
-
- /* create a 12 byte random value, convert to base 64, insert in zrtpIdOwn table */
- randomZRTP(localZid, IDENTIFIER_LEN);
- b64len = b64Encode(localZid, IDENTIFIER_LEN, b64zid, IDENTIFIER_LEN+IDENTIFIER_LEN);
-
- SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdOwn, strlen(insertZrtpIdOwn)+1, &stmt, NULL));
-
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64zid, b64len, SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int(stmt, 2, type));
- SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- }
- else if (found > 1) {
- if (errString)
- snprintf(errString, DB_CACHE_ERR_BUFF_SIZE,
- "ZRTP cache inconsistent. Found %d matching local ZID for account: %s\n", found, accountInfo);
- return 1;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-/*
- * SQLite use the following table structure to manage some internal data
- *
- * CREATE TABLE sqlite_master (
- * type TEXT,
- * name TEXT,
- * tbl_name TEXT,
- * rootpage INTEGER,
- * sql TEXT
- * );
- */
-
-static int openCache(const char* name, void **vpdb, char *errString)
-{
- sqlite3_stmt *stmt;
- int found = 0;
- sqlite3 **pdb = (sqlite3**)vpdb;
- sqlite3 *db;
-
-#ifdef SQLITE_USE_V2
- int rc = sqlite3_open_v2(name, pdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);
-#else
- int rc = sqlite3_open(name, pdb);
-#endif
- db = *pdb;
- if (rc) {
- ERRMSG;
- return(rc);
- }
-
- /* check if ZRTP cache tables are already available, look if zrtpIdOwn is available */
- SQLITE_CHK(SQLITE_PREPARE(db, lookupTables, strlen(lookupTables)+1, &stmt, NULL));
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
-
- if (rc == SQLITE_ROW) {
- found++;
- }
- else if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- /* If table zrtpOwnId not found then we have an empty cache DB */
- if (found == 0) {
- rc = createTables(db, errString);
- if (rc)
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-static int closeCache(void *vdb)
-{
-
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_close(db);
- return SQLITE_OK;
-}
-
-static int clearCache(void *vdb, char *errString)
-{
-
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt * stmt;
- int rc;
-
- rc = SQLITE_PREPARE(db, dropZrtpIdOwn, strlen(dropZrtpIdOwn)+1, &stmt, NULL);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
-
- rc = createTables(db, errString);
- if (rc)
- return rc;
- return SQLITE_OK;
-}
-
-static int insertZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc = 0;
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- if (accountInfo == NULL) {
- accountInfo = defaultAccountString;
- }
-
- /* Get B64 code for remoteZid */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpNames, strlen(insertZrtpNames)+1, &stmt, NULL));
-
- /* For *_bind_* methods: column index starts with 1 (one), not zero */
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_int(stmt, 4, zidName->flags));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 5, (int64_t)time(NULL)));
- if (zidName->name != NULL) {
- SQLITE_CHK(sqlite3_bind_text(stmt, 6, zidName->name, strlen(zidName->name), SQLITE_STATIC));
- }
- else {
- SQLITE_CHK(sqlite3_bind_text(stmt, 6, "_NO_NAME_", 9, SQLITE_STATIC));
- }
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-
-}
-
-
-static int updateZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc = 0;
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- if (accountInfo == NULL) {
- accountInfo = defaultAccountString;
- }
-
- /* Get B64 code for remoteZid */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpNames, strlen(updateZrtpNames)+1, &stmt, NULL));
-
- /* For *_bind_* methods: column index starts with 1 (one), not zero */
- /* Select for update with the following values */
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
- /* Update the following vaulues */
- SQLITE_CHK(sqlite3_bind_int(stmt, 4, zidName->flags));
- SQLITE_CHK(sqlite3_bind_int64(stmt, 5, (int64_t)time(NULL)));
- if (zidName->name != NULL) {
- SQLITE_CHK(sqlite3_bind_text(stmt, 6, zidName->name, strlen(zidName->name), SQLITE_STATIC));
- }
- else {
- SQLITE_CHK(sqlite3_bind_text(stmt, 6, "_NO_NAME_", 9, SQLITE_STATIC));
- }
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-
-}
-
-static int readZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
- const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
- sqlite3 *db = (sqlite3*)vdb;
- sqlite3_stmt *stmt;
- int rc;
- int found = 0;
-
- char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
- char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
- if (accountInfo == NULL) {
- accountInfo = defaultAccountString;
- }
- /* Get B64 code for remoteZid */
- b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
- /* Get B64 code for localZid */
- b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
- SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpNames, strlen(selectZrtpNames)+1, &stmt, NULL));
-
- SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
- SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
- /* Getting data from result set: column index starts with 0 (zero), not one */
- while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
- zidName->flags = sqlite3_column_int(stmt, 0);
- strncpy(zidName->name, (const char*)sqlite3_column_text(stmt, 2), zidName->nameLength);
- zidName->nameLength = sqlite3_column_bytes(stmt, 2); /* Return number of bytes in string */
- found++;
- }
- sqlite3_finalize(stmt);
-
- if (rc != SQLITE_DONE) {
- ERRMSG;
- return rc;
- }
- if (found == 0)
- zidName->flags = 0;
- else if (found > 1) {
- if (errString)
- snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, "ZRTP name cache inconsistent. More than one ZID name found: %d\n", found);
- return 1;
- }
- return SQLITE_OK;
-
- cleanup:
- sqlite3_finalize(stmt);
- return rc;
-}
-
-void getDbCacheOps(dbCacheOps_t *ops)
-{
- ops->openCache = openCache;
- ops->closeCache = closeCache;
- ops->cleanCache = clearCache;
-
- ops->readLocalZid = readLocalZid;
-
- ops->readRemoteZidRecord = readRemoteZidRecord;
- ops->updateRemoteZidRecord = updateRemoteZidRecord;
- ops->insertRemoteZidRecord = insertRemoteZidRecord;
-
- ops->readZidNameRecord = readZidNameRecord;
- ops->updateZidNameRecord = updateZidNameRecord;
- ops->insertZidNameRecord = insertZidNameRecord;
-}
-