* #40116: Add zrtp related files, update libzrtpcpp
diff --git a/jni/Android.mk b/jni/Android.mk
index fb0e9ef..d2f2534 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -70,7 +70,10 @@
@echo "in $(MY_JNI_WRAP) target"
./make-swig.sh
-
+#LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CPPFLAGS += -frtti
+LOCAL_CPPFLAGS += -fexceptions
+#LOCAL_CPPFLAGS += -fpermissive
LOCAL_SRC_FILES := \
$(LOCAL_SRC_PATH)/conference.cpp \
@@ -134,10 +137,9 @@
$(LOCAL_SRC_PATH)/sip/pattern.cpp \
$(LOCAL_SRC_PATH)/sip/sdes_negotiator.cpp \
$(LOCAL_SRC_PATH)/sip/pres_sub_client.cpp \
- $(LOCAL_SRC_PATH)/sip/pres_sub_server.cpp
-
- # $(LOCAL_SRC_PATH)/audio/audiortp/audio_zrtp_session.cpp \
- # $(LOCAL_SRC_PATH)/audio/audiortp/zrtp_session_callback.cpp \
+ $(LOCAL_SRC_PATH)/sip/pres_sub_server.cpp \
+ $(LOCAL_SRC_PATH)/audio/audiortp/audio_zrtp_session.cpp \
+ $(LOCAL_SRC_PATH)/audio/audiortp/zrtp_session_callback.cpp \
# FIXME
LOCAL_C_INCLUDES += $(LOCAL_SRC_PATH)/.. \
@@ -156,9 +158,9 @@
$(MY_SPEEX) \
$(MY_SPEEX)/include \
$(MY_LIBYAML)/inc \
- $(MY_LIBZRTPCPP)/src/ \
$(MY_LIBZRTPCPP) \
$(MY_LIBZRTPCPP)/zrtp \
+ $(MY_LIBZRTPCPP)/zrtp/libzrtpcpp \
$(MY_CCRTP)/src \
$(MY_LIBSAMPLE)/src \
$(MY_OPENSSL)/include \
@@ -171,8 +173,8 @@
libsndfile/sources/src \
libpcre/sources \
${MY_COMMONCPP}/inc \
- ${MY_LIBZRTPCPP}/zrtp \
- ${MY_LIBZRTPCPP}/clients/ccrtp
+
+
LOCAL_MODULE := libsflphone
@@ -185,7 +187,7 @@
-DHAVE_SPEEX_CODEC \
-DHAVE_GSM_CODEC \
-w \
- -std=c++11 -frtti -fexceptions -fpermissive \
+ -std=c++11 -fexceptions -fpermissive \
-DAPP_NAME=\"sflphone\" \
-DSWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON \
-DDEBUG_DIRECTOR_OWNED \
@@ -212,12 +214,13 @@
libsamplerate \
libspeex \
libcrypto_static \
+ libzrtpcpp \
libsndfile \
libccrtp1 \
libexpat_shared \
libspeexresampler \
- libyaml \
- libzrtpcpp
+ libyaml
+
diff --git a/jni/Application.mk b/jni/Application.mk
index cc70c4d..e1e1d47 100644
--- a/jni/Application.mk
+++ b/jni/Application.mk
@@ -28,6 +28,18 @@
# as that of the covered work.
+BASE_PJSIP_FLAGS := -DPJ_ANDROID=1
+# about codecs
+BASE_PJSIP_FLAGS += -DPJMEDIA_HAS_G729_CODEC=0 -DPJMEDIA_HAS_G726_CODEC=0 \
+ -DPJMEDIA_HAS_ILBC_CODEC=0 -DPJMEDIA_HAS_G722_CODEC=0 \
+ -DPJMEDIA_HAS_SPEEX_CODEC=0 -DPJMEDIA_HAS_GSM_CODEC=0 \
+ -DPJMEDIA_HAS_SILK_CODEC=0 -DPJMEDIA_HAS_CODEC2_CODEC=0 \
+ -DPJMEDIA_HAS_G7221_CODEC=0 -DPJMEDIA_HAS_WEBRTC_CODEC=0 \
+ -DPJMEDIA_HAS_OPUS_CODEC=0
+
+# TLS ZRTP
+BASE_PJSIP_FLAGS += -DPJ_HAS_SSL_SOCK=1 -DPJMEDIA_HAS_ZRTP=1
+
NDK_TOOLCHAIN_VERSION := 4.8
APP_PLATFORM := android-14
@@ -35,6 +47,7 @@
APP_STL := gnustl_shared
APP_ABI = armeabi-v7a x86
+
APP_MODULES += libcodec_ulaw
APP_MODULES += libcodec_alaw
APP_MODULES += libcodec_g722
diff --git a/jni/libccrtp/Android.mk b/jni/libccrtp/Android.mk
index 3433146..aaee5ba 100644
--- a/jni/libccrtp/Android.mk
+++ b/jni/libccrtp/Android.mk
@@ -6,11 +6,11 @@
LT_VERSION =
LT_RELEASE =
-SHARED_FLAGS = "-no-undefined"
+#SHARED_FLAGS = "-no-undefined"
SRTP_OPENSSL =
SRTP_GCRYPT =
-LOCAL_CPPFLAGS += -std=gnu++0x -fexceptions
+#LOCAL_CPPFLAGS += -std=gnu++0x -fexceptions -frtti
LOCAL_C_INCLUDES += $(MY_LOCAL_PATH)/src \
$(MY_LOCAL_PATH) \
diff --git a/jni/libpjsip/android_toolchain/pjlib/Android.mk b/jni/libpjsip/android_toolchain/pjlib/Android.mk
index 4c84f13..71cad0e 100644
--- a/jni/libpjsip/android_toolchain/pjlib/Android.mk
+++ b/jni/libpjsip/android_toolchain/pjlib/Android.mk
@@ -10,7 +10,7 @@
PJLIB_DIR := libpjsip/sources/pjlib
PJLIB_SRC_DIR := $(PJLIB_DIR)/src/pj
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/libopenssl/include \
+LOCAL_C_INCLUDES += libopenssl/include \
$(PJLIB_DIR)/include \
LOCAL_SRC_FILES := $(PJLIB_SRC_DIR)/addr_resolv_sock.c \
diff --git a/jni/libpjsip/android_toolchain/pjsip/Android.mk b/jni/libpjsip/android_toolchain/pjsip/Android.mk
index 3e814e5..e33748c 100644
--- a/jni/libpjsip/android_toolchain/pjsip/Android.mk
+++ b/jni/libpjsip/android_toolchain/pjsip/Android.mk
@@ -10,7 +10,8 @@
$(PJSIP_DIR)/../pjlib/include \
$(PJSIP_DIR)/../pjlib-util/include \
$(PJSIP_DIR)/../pjnath/include \
- $(PJSIP_DIR)/../pjmedia/include
+ $(PJSIP_DIR)/../pjmedia/include \
+ libopenssl/sources/include
LOCAL_CFLAGS := $(MY_PJSIP_FLAGS)
@@ -60,12 +61,8 @@
$(PJSIPSIMPLE_SRC_DIR)/presence_body.c \
$(PJSIPSIMPLE_SRC_DIR)/publishc.c \
$(PJSIPSIMPLE_SRC_DIR)/rpid.c \
- $(PJSIPSIMPLE_SRC_DIR)/xpidf.c
-
-ifeq ($(MY_USE_TLS),1)
-LOCAL_SRC_FILES += $(PJSIP_SRC_DIR)/sip_transport_tls.c
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../openssl/sources/include
-endif
+ $(PJSIPSIMPLE_SRC_DIR)/xpidf.c \
+ $(PJSIP_SRC_DIR)/sip_transport_tls.c
include $(BUILD_STATIC_LIBRARY)
\ No newline at end of file
diff --git a/jni/libpjsip/sources/pjlib/include/pj/config_site.h b/jni/libpjsip/sources/pjlib/include/pj/config_site.h
index e69de29..c48ea8e 100644
--- a/jni/libpjsip/sources/pjlib/include/pj/config_site.h
+++ b/jni/libpjsip/sources/pjlib/include/pj/config_site.h
@@ -0,0 +1,485 @@
+/*
+ * This file contains several sample settings especially for Windows
+ * Mobile and Symbian targets. You can include this file in your
+ * <pj/config_site.h> file.
+ *
+ * The Windows Mobile and Symbian settings will be activated
+ * automatically if you include this file.
+ *
+ * In addition, you may specify one of these macros (before including
+ * this file) to activate additional settings:
+ *
+ * #define PJ_CONFIG_NOKIA_APS_DIRECT
+ * Use this macro to activate the APS-Direct feature. Please see
+ * http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct for more
+ * info.
+ *
+ * #define PJ_CONFIG_WIN32_WMME_DIRECT
+ * Configuration to activate "APS-Direct" media mode on Windows or
+ * Windows Mobile, useful for testing purposes only.
+ */
+
+
+/*
+ * Typical configuration for WinCE target.
+ */
+#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+
+ /*
+ * PJLIB settings.
+ */
+
+ /* Disable floating point support */
+ #define PJ_HAS_FLOATING_POINT 0
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* Select codecs to disable */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_ILBC_CODEC 0
+
+ /* We probably need more buffers on WM, so increase the limit */
+ #define PJMEDIA_SOUND_BUFFER_COUNT 32
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /* For CPU reason, disable speex AEC and use the echo suppressor. */
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+
+ /* Previously, resampling is disabled due to performance reason and
+ * this condition prevented some 'light' wideband codecs (e.g: G722.1)
+ * to work along with narrowband codecs. Lately, some tests showed
+ * that 16kHz <-> 8kHz resampling using libresample small filter was
+ * affordable on ARM9 260 MHz, so here we decided to enable resampling.
+ * Note that it is important to make sure that libresample is created
+ * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must
+ * be set to 3 or 4 so pjsua-lib will apply small filter resampling.
+ */
+ //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE
+ #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+
+ /* Use the lighter WSOLA implementation */
+ #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Set maximum number of dialog/transaction/calls to minimum to reduce
+ * memory usage
+ */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /*
+ * PJSUA settings
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of objects to minimum to reduce memory usage */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+
+#endif /* PJ_WIN32_WINCE */
+
+
+/*
+ * Typical configuration for Symbian OS target
+ */
+#if defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0
+
+ /*
+ * PJLIB settings.
+ */
+
+ /* Disable floating point support */
+ #define PJ_HAS_FLOATING_POINT 0
+
+ /* Misc PJLIB setting */
+ #define PJ_MAXPATH 80
+
+ /* This is important for Symbian. Symbian lacks vsnprintf(), so
+ * if the log buffer is not long enough it's possible that
+ * large incoming packet will corrupt memory when the log tries
+ * to log the packet.
+ */
+ #define PJ_LOG_MAX_SIZE (PJSIP_MAX_PKT_LEN+500)
+
+ /* Since we don't have threads, log buffer can use static buffer
+ * rather than stack
+ */
+ #define PJ_LOG_USE_STACK_BUFFER 0
+
+ /* Disable check stack since it increases footprint */
+ #define PJ_OS_HAS_CHECK_STACK 0
+
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* Disable non-Symbian audio devices */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 0
+
+ /* Select codecs to disable */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_ILBC_CODEC 0
+ #define PJMEDIA_HAS_G722_CODEC 0
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /* For CPU reason, disable speex AEC and use the echo suppressor. */
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+
+ /* Previously, resampling is disabled due to performance reason and
+ * this condition prevented some 'light' wideband codecs (e.g: G722.1)
+ * to work along with narrowband codecs. Lately, some tests showed
+ * that 16kHz <-> 8kHz resampling using libresample small filter was
+ * affordable on ARM9 222 MHz, so here we decided to enable resampling.
+ * Note that it is important to make sure that libresample is created
+ * using small filter. For example PJSUA_DEFAULT_CODEC_QUALITY must
+ * be set to 3 or 4 so pjsua-lib will apply small filter resampling.
+ */
+ //#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_NONE
+ #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+
+ /* Use the lighter WSOLA implementation */
+ #define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA_LITE
+
+ /* We probably need more buffers especially if MDA audio backend
+ * is used, so increase the limit
+ */
+ #define PJMEDIA_SOUND_BUFFER_COUNT 32
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Disable safe module access, since we don't use multithreading */
+ #define PJSIP_SAFE_MODULE 0
+
+ /* Use large enough packet size */
+ #define PJSIP_MAX_PKT_LEN 2000
+
+ /* Symbian has problem with too many large blocks */
+ #define PJSIP_POOL_LEN_ENDPT 1000
+ #define PJSIP_POOL_INC_ENDPT 1000
+ #define PJSIP_POOL_RDATA_LEN 2000
+ #define PJSIP_POOL_RDATA_INC 2000
+ #define PJSIP_POOL_LEN_TDATA 2000
+ #define PJSIP_POOL_INC_TDATA 512
+ #define PJSIP_POOL_LEN_UA 2000
+ #define PJSIP_POOL_INC_UA 1000
+ #define PJSIP_POOL_TSX_LAYER_LEN 256
+ #define PJSIP_POOL_TSX_LAYER_INC 256
+ #define PJSIP_POOL_TSX_LEN 512
+ #define PJSIP_POOL_TSX_INC 128
+
+ /*
+ * PJSUA settings.
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of dialog/transaction/calls to minimum */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /* Other pjsua settings */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+#endif
+
+
+/*
+ * Additional configuration to activate APS-Direct feature for
+ * Nokia S60 target
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct
+ */
+#ifdef PJ_CONFIG_NOKIA_APS_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Enable APS sound device backend and disable MDA & VAS */
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 1
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 0
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* And selectively enable which codecs are supported by the handset */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+
+#endif
+
+
+/*
+ * Additional configuration to activate VAS-Direct feature for
+ * Nokia S60 target
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Nokia_APS_VAS_Direct
+ */
+#ifdef PJ_CONFIG_NOKIA_VAS_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Enable VAS sound device backend and disable MDA & APS */
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0
+ #define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 1
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* And selectively enable which codecs are supported by the handset */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+
+#endif
+
+
+/*
+ * Configuration to activate "APS-Direct" media mode on Windows,
+ * useful for testing purposes only.
+ */
+#ifdef PJ_CONFIG_WIN32_WMME_DIRECT
+
+ /* MUST use switchboard rather than the conference bridge */
+ #define PJMEDIA_CONF_USE_SWITCH_BOARD 1
+
+ /* Only WMME supports the "direct" feature */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 1
+
+ /* Enable passthrough codec framework */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODECS 1
+
+ /* Only PCMA and PCMU are supported by WMME-direct */
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 0
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 0
+ #define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 0
+
+#endif
+
+/*
+ * iPhone sample settings.
+ */
+#if PJ_CONFIG_IPHONE
+ /*
+ * PJLIB settings.
+ */
+
+ /* Both armv6 and armv7 has FP hardware support.
+ * See https://trac.pjsip.org/repos/ticket/1589 for more info
+ */
+ #define PJ_HAS_FLOATING_POINT 1
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* We have our own native CoreAudio backend */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 0
+ #define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO 1
+
+ /* The CoreAudio backend has built-in echo canceller! */
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+
+ /* Disable some codecs */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_G722_CODEC 0
+
+ /* Use the built-in CoreAudio's iLBC codec (yay!) */
+ #define PJMEDIA_HAS_ILBC_CODEC 1
+ #define PJMEDIA_ILBC_CODEC_USE_COREAUDIO 1
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Increase allowable packet size, just in case */
+ //#define PJSIP_MAX_PKT_LEN 2000
+
+ /*
+ * PJSUA settings.
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of dialog/transaction/calls to minimum */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /* Other pjsua settings */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+
+#endif
+
+/*
+ * Android sample settings.
+ */
+#if PJ_CONFIG_ANDROID
+
+ #define PJ_ANDROID 1
+
+ /*
+ * PJLIB settings.
+ */
+
+ /* Disable floating point support */
+ #undef PJ_HAS_FLOATING_POINT
+ #define PJ_HAS_FLOATING_POINT 0
+
+ /*
+ * PJMEDIA settings
+ */
+
+ /* We have our own OpenSL ES backend */
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+ #define PJMEDIA_AUDIO_DEV_HAS_WMME 0
+ #define PJMEDIA_AUDIO_DEV_HAS_OPENSL 1
+ #define PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI 0
+
+ /* Disable some codecs */
+ #define PJMEDIA_HAS_L16_CODEC 0
+ #define PJMEDIA_HAS_G722_CODEC 0
+
+ /* Fine tune Speex's default settings for best performance/quality */
+ #define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 5
+
+ /*
+ * PJSIP settings.
+ */
+
+ /* Increase allowable packet size, just in case */
+ //#define PJSIP_MAX_PKT_LEN 2000
+
+ /*
+ * PJSUA settings.
+ */
+
+ /* Default codec quality, previously was set to 5, however it is now
+ * set to 4 to make sure pjsua instantiates resampler with small filter.
+ */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+
+ /* Set maximum number of dialog/transaction/calls to minimum */
+ #define PJSIP_MAX_TSX_COUNT 31
+ #define PJSIP_MAX_DIALOG_COUNT 31
+ #define PJSUA_MAX_CALLS 4
+
+ /* Other pjsua settings */
+ #define PJSUA_MAX_ACC 4
+ #define PJSUA_MAX_PLAYERS 4
+ #define PJSUA_MAX_RECORDERS 4
+ #define PJSUA_MAX_CONF_PORTS (PJSUA_MAX_CALLS+2*PJSUA_MAX_PLAYERS)
+ #define PJSUA_MAX_BUDDIES 32
+#endif
+
+
+/*
+ * BB10
+ */
+#if defined(PJ_CONFIG_BB10) && PJ_CONFIG_BB10
+ /* Quality 3 - 4 to use resampling small filter */
+ #define PJSUA_DEFAULT_CODEC_QUALITY 4
+ #define PJMEDIA_HAS_LEGACY_SOUND_API 0
+ #undef PJMEDIA_HAS_SPEEX_AEC
+ #define PJMEDIA_HAS_SPEEX_AEC 0
+ #undef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
+ #define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+#endif
+
+
+/*
+ * Minimum size
+ */
+#ifdef PJ_CONFIG_MINIMAL_SIZE
+
+# undef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+# define PJ_LOG_MAX_LEVEL 0
+# define PJ_ENABLE_EXTRA_CHECK 0
+# define PJ_HAS_ERROR_STRING 0
+# undef PJ_IOQUEUE_MAX_HANDLES
+/* Putting max handles to lower than 32 will make pj_fd_set_t size smaller
+ * than native fdset_t and will trigger assertion on sock_select.c.
+ */
+# define PJ_IOQUEUE_MAX_HANDLES 32
+# define PJ_CRC32_HAS_TABLES 0
+# define PJSIP_MAX_TSX_COUNT 15
+# define PJSIP_MAX_DIALOG_COUNT 15
+# define PJSIP_UDP_SO_SNDBUF_SIZE 4000
+# define PJSIP_UDP_SO_RCVBUF_SIZE 4000
+# define PJMEDIA_HAS_ALAW_ULAW_TABLE 0
+
+#elif defined(PJ_CONFIG_MAXIMUM_SPEED)
+# define PJ_SCANNER_USE_BITWISE 0
+# undef PJ_OS_HAS_CHECK_STACK
+# define PJ_OS_HAS_CHECK_STACK 0
+# define PJ_LOG_MAX_LEVEL 3
+# define PJ_ENABLE_EXTRA_CHECK 0
+# define PJ_IOQUEUE_MAX_HANDLES 5000
+# define PJSIP_MAX_TSX_COUNT ((640*1024)-1)
+# define PJSIP_MAX_DIALOG_COUNT ((640*1024)-1)
+# define PJSIP_UDP_SO_SNDBUF_SIZE (24*1024*1024)
+# define PJSIP_UDP_SO_RCVBUF_SIZE (24*1024*1024)
+# define PJ_DEBUG 0
+# define PJSIP_SAFE_MODULE 0
+# define PJ_HAS_STRICMP_ALNUM 0
+# define PJ_HASH_USE_OWN_TOLOWER 1
+# define PJSIP_UNESCAPE_IN_PLACE 1
+
+# if defined(PJ_WIN32) || defined(PJ_WIN64)
+# define PJSIP_MAX_NET_EVENTS 10
+# endif
+
+# define PJSUA_MAX_CALLS 512
+
+#endif
+
diff --git a/jni/libucommon/Android.mk b/jni/libucommon/Android.mk
index 364c629..7a2ffd5 100644
--- a/jni/libucommon/Android.mk
+++ b/jni/libucommon/Android.mk
@@ -6,8 +6,6 @@
LOCAL_MODULE := libccgnu2
-LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib
-
LOCAL_CPPFLAGS += -std=c++11 -Wno-psabi -frtti -pthread -fexceptions
LOCAL_C_INCLUDES += $(LOCAL_COMMONCPP_PATH)/ \
diff --git a/jni/libucommon/sources/inc/ucommon/cpr.h b/jni/libucommon/sources/inc/ucommon/cpr.h
index 0776ce5..c260ede 100644
--- a/jni/libucommon/sources/inc/ucommon/cpr.h
+++ b/jni/libucommon/sources/inc/ucommon/cpr.h
@@ -26,6 +26,9 @@
#include <ucommon/platform.h>
#endif
+
+#include <new>
+
#ifndef _UCOMMON_CPR_H_
#define _UCOMMON_CPR_H_
@@ -82,7 +85,7 @@
* @param size of object being constructed.
* @return memory allocated from heap.
*/
-inline void *operator new(size_t size)
+inline void *operator new(size_t size) throw(std::bad_alloc)
{return cpr_memalloc(size);}
/**
@@ -90,7 +93,7 @@
* @param size of memory needed for object array.
* @return memory allocated from heap.
*/
-inline void *operator new[](size_t size)
+inline void *operator new[](size_t size) throw(std::bad_alloc)
{return cpr_memalloc(size);}
#endif
diff --git a/jni/libzrtp/Android.mk b/jni/libzrtp/Android.mk
index 7b07d6f..740b64c 100644
--- a/jni/libzrtp/Android.mk
+++ b/jni/libzrtp/Android.mk
@@ -5,24 +5,32 @@
# Define and build the zrtpcpp static lib
#
include $(CLEAR_VARS)
-LOCAL_MODULE := libzrtpcpp
-LOCAL_CPP_FEATURES := exceptions
-MY_CCRTP = libccrtp/sources
+
+LOCAL_MODULE := libzrtpcpp
+#LOCAL_CPP_FEATURES := exceptions
+
+#LOCAL_CPPFLAGS += -std=c++11
+LOCAL_CPPFLAGS += -frtti
+LOCAL_CPPFLAGS += -fexceptions
+#LOCAL_CPPFLAGS += -fpermissive
+
MY_COMMONCPP = libucommon/sources
+MY_CCRTP = libccrtp/sources
# include paths for zrtpcpp modules
LOCAL_C_INCLUDES += $(ROOT_SRC_PATH) \
$(ROOT_SRC_PATH)/srtp \
$(ROOT_SRC_PATH)/zrtp \
- $(ROOT_SRC_PATH)/clients/ccrtp \
- $(MY_CCRTP)/src \
+ $(ROOT_SRC_PATH)/zrtp/libzrtpcpp \
${MY_COMMONCPP}/inc \
+ $(MY_CCRTP)/src \
$(ROOT_SRC_PATH)/bnlib \
$(ROOT_SRC_PATH)/bnlib/ec
EC_SRCS = $(ROOT_SRC_PATH)/bnlib/ec/ec.c \
- $(ROOT_SRC_PATH)/bnlib/ec/ecdh.c
+ $(ROOT_SRC_PATH)/bnlib/ec/ecdh.c \
+ $(ROOT_SRC_PATH)/bnlib/ec/curve25519-donna.c
COMMON_SRCS = $(ROOT_SRC_PATH)/common/osSpecifics.c \
$(ROOT_SRC_PATH)/common/Thread.cpp \
@@ -67,7 +75,7 @@
$(ROOT_SRC_PATH)/zrtp/ZrtpTextData.cpp \
$(ROOT_SRC_PATH)/zrtp/ZrtpConfigure.cpp \
$(ROOT_SRC_PATH)/zrtp/ZrtpCWrapper.cpp \
- $(ROOT_SRC_PATH)/clients/ccrtp/ZrtpQueue.cpp \
+ $(ROOT_SRC_PATH)/zrtp/ZrtpQueue.cpp \
$(ROOT_SRC_PATH)/zrtp/Base32.cpp \
$(ROOT_SRC_PATH)/zrtp/zrtpB64Encode.c \
$(ROOT_SRC_PATH)/zrtp/zrtpB64Decode.c \
@@ -80,6 +88,10 @@
$(ROOT_SRC_PATH)/zrtp/crypto/sha384.cpp \
$(ROOT_SRC_PATH)/zrtp/crypto/aesCFB.cpp \
$(ROOT_SRC_PATH)/zrtp/crypto/twoCFB.cpp \
+ $(ROOT_SRC_PATH)/zrtp/crypto/skein256.cpp \
+ $(ROOT_SRC_PATH)/zrtp/crypto/skeinMac256.cpp \
+ $(ROOT_SRC_PATH)/zrtp/crypto/skein384.cpp \
+ $(ROOT_SRC_PATH)/zrtp/crypto/skeinMac384.cpp \
$(ROOT_SRC_PATH)/zrtp/crypto/sha2.c \
$(ROOT_SRC_PATH)/zrtp/ZIDCacheFile.cpp \
$(ROOT_SRC_PATH)/zrtp/ZIDRecordFile.cpp \
@@ -104,6 +116,8 @@
$(COMMON_SRCS) \
$(BNLIB_SRCS)
+LOCAL_STATIC_LIBRARY += libccrtp1
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/jni/libzrtp/sources/.gitignore b/jni/libzrtp/sources/.gitignore
index ee3d613..4876ff9 100644
--- a/jni/libzrtp/sources/.gitignore
+++ b/jni/libzrtp/sources/.gitignore
@@ -1,4 +1,4 @@
-build/
+build*/
autoconf/
doc/html/
configure
@@ -16,4 +16,8 @@
*.pc
*.spec
*~
+.DS_Store
+._.DS_Store
+._buildmac
+.directory
diff --git a/jni/libzrtp/sources/CMakeLists.txt b/jni/libzrtp/sources/CMakeLists.txt
index 430f5e7..8e0bb80 100755
--- a/jni/libzrtp/sources/CMakeLists.txt
+++ b/jni/libzrtp/sources/CMakeLists.txt
@@ -11,84 +11,54 @@
cmake_minimum_required(VERSION 2.6)
PROJECT(libzrtpcpp)
-set (PACKAGE libzrtpcpp)
-set (VERSION 3.0.0)
-set (SOVERSION ${VERSION})
-STRING(REGEX REPLACE "[.].*$" "" SOVERSION ${SOVERSION})
-SET(CPACK_PACKAGE_VERSION_MAJOR ${SOVERSION})
-SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION})
-SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION})
-STRING(REGEX REPLACE "[.][0-9]*$" "" CPACK_PACKAGE_VERSION_MINOR ${VERSION})
-STRING(REGEX REPLACE ".*[.]" "" CPACK_PACKAGE_VERSION_MINOR ${CPACK_PACKAGE_VERSION_MINOR})
-STRING(REGEX REPLACE ".*[.]" "" CPACK_PACKAGE_VERSION_PATCH ${VERSION})
+SET(CPACK_PACKAGE_VERSION_MAJOR 4)
+SET(CPACK_PACKAGE_VERSION_MINOR 1)
+SET(CPACK_PACKAGE_VERSION_PATCH 1)
-include(cmake/Modules/AutoArgs.cmake)
-include(cmake/Modules/FindGcryptConfig.cmake)
+set (VERSION 4.1.1)
+set (SOVERSION 4)
-# Define supported -Denable-* command line parameters.
+# Define supported command line parameters.
#
-# Example to build the tivi client: cmake -Denable-tivi=true ..
+# Example to build the tivi client: cmake -DTIVI=true ..
# Without any options cmake generates libzrtpcpp for use with GNU ccRTP
#
-enable_arg(ccrtp false "Build library to use with GNU ccRTP.")
-enable_arg(crypto_standalone false "Use embedded crypto and big number modules.")
-enable_arg(tivi false "Build library for the tivi client, implies '-Denable-crypto_standalone=true'.")
-enable_arg(sqlite false "Use SQLite DB as backend for ZRTP cache.")
-args_help()
+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 (enable_ccrtp AND enable_tivi)
+if (CCRTP AND TIVI)
MESSAGE(FATAL_ERROR "Cannot build more than one client at once. Use different build directories.")
endif()
-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})
+if (CCRTP)
set (PACKAGE libzrtpcpp)
set(zrtplibName zrtpcpp)
-elseif (enable_tivi)
+elseif (TIVI)
set (PACKAGE libzrtptivi)
set(zrtplibName zrtptivi)
- set (enable_crypto_standalone true)
+ 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(enable_ccrtp true)
+ set(CCRTP true)
set(zrtplibName zrtpcpp)
endif()
-if (enable_crypto_standalone)
- set(CRYPTO_STANDALONE TRUE)
-endif()
-
-if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
- add_custom_target(cleandist
- WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}[-_]*.gz"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}_*.dsc"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}-*.rpm"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/*${PACKAGE}*[-_]*.deb"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}-*.zip"
- COMMAND rm -f "${CMAKE_CURRENT_BINARY_DIR}/*${PACKAGE}*.changes"
- )
-
- add_custom_target(dist
- DEPENDS cleandist
- WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
- COMMAND git archive --format tar --output="${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}-${VERSION}.tar" --prefix="${PACKAGE}-${VERSION}/" HEAD
- COMMAND gzip "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE}-${VERSION}.tar"
- )
-endif()
if(MSVC60)
set(BUILD_STATIC ON CACHE BOOL "static linking only" FORCE)
@@ -100,7 +70,10 @@
# set to true for debug and trace during CMakeLists development
# set(CMAKE_VERBOSE_MAKEFILE TRUE)
-MESSAGE( STATUS "Configuring GNU ${PROJECT_NAME} ${VERSION} for ${PACKAGE}...")
+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} ...")
# include most of the fine stuff we need
include(FindPkgConfig)
@@ -123,7 +96,7 @@
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(string.h HAVE_STRING_H)
-if (NOT enable_crypto_standalone)
+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
@@ -165,7 +138,7 @@
configure_file(${CMAKE_SOURCE_DIR}/bnlib/bnconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/bnconfig.h)
endif()
-if (enable_sqlite)
+if (SQLITE)
pkg_check_modules(SQLITE3 sqlite3>=3.7)
if (SQLITE3_FOUND)
check_include_files(sqlite3.h HAVE_SQLITE_H)
@@ -175,148 +148,119 @@
endif()
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)
-
-# necessary and required modules checked, ready to generate config.h
-configure_file(libzrtpcpp-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/libzrtpcpp-config.h)
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-# 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}/libzrtpcpp.pc @ONLY)
-
-configure_file(libzrtpcpp.spec.cmake ${CMAKE_CURRENT_BINARY_DIR}/libzrtpcpp.spec @ONLY)
-
-#to make sure includes are first taken from those directory
-include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
+# 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)
add_definitions(-g -O2 -fno-strict-aliasing)
if(CMAKE_COMPILER_IS_GNUCXX)
- add_definitions(-Wno-long-long -Wno-char-subscripts)
- add_definitions(-Wall -pedantic)
- add_definitions(-DNEW_STDCPP)
+# 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)
endif()
include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/zrtp)
-if(enable_standalone)
- include_directories (${CMAKE_CURRENT_SOURCE_DIR}/bnlib)
+include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/zrtp)
+
+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 ****
#
-if (NOT enable_ccrtp)
- set (sdes_src ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpSdesStream.cpp)
-endif()
-
set(zrtp_src_no_cache
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpCallbackWrapper.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZRtp.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpCrc32.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketCommit.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketConf2Ack.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketConfirm.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketDHPart.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketGoClear.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketClearAck.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketHelloAck.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketHello.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketError.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketErrorAck.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketPingAck.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketPing.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketSASrelay.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpPacketRelayAck.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpStateClass.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpTextData.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpConfigure.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZrtpCWrapper.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/Base32.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/common/osSpecifics.c ${sdes_src})
+ ${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_CURRENT_SOURCE_DIR}/bnlib/bn00.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/lbn00.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/bn.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/lbnmem.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/sieve.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/prime.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/bnprint.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/jacobi.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/germain.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/ec/ec.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/ec/ecdh.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bnlib/bnprint.c)
+ ${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_CURRENT_SOURCE_DIR}/zrtp/crypto/zrtpDH.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/hmac256.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/sha256.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/hmac384.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/sha384.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/aesCFB.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/twoCFB.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/crypto/sha2.c)
+ ${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
-if (NOT enable_sqlite)
- set(zrtp_src ${zrtp_src_no_cache}
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZIDCacheFile.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZIDRecordFile.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_CURRENT_SOURCE_DIR}/zrtp/ZIDCacheDb.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/ZIDRecordDb.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/zrtpB64Encode.c
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/zrtpB64Decode.c
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtp/zrtpCacheSqliteBackend.c)
+ ${CMAKE_SOURCE_DIR}/zrtp/ZIDCacheDb.cpp
+ ${CMAKE_SOURCE_DIR}/zrtp/ZIDRecordDb.cpp
+ ${CMAKE_SOURCE_DIR}/zrtp/zrtpCacheSqliteBackend.c)
+
endif()
-if (enable_ccrtp)
+if (CCRTP)
add_subdirectory(clients/ccrtp)
add_subdirectory(demo)
endif()
-if (enable_tivi)
+if (TIVI)
add_subdirectory(clients/tivi)
endif()
+if (CORE_LIB)
+ add_subdirectory(clients/no_client)
+endif()
+
##very usefull for macosx, specially when using gtkosx bundler
if(APPLE)
if (NOT CMAKE_INSTALL_NAME_DIR)
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE STRING "CMAKE_INSTALL_NAME_DIR set for macosx" )
endif (NOT CMAKE_INSTALL_NAME_DIR)
endif(APPLE)
-
-
diff --git a/jni/libzrtp/sources/COPYING b/jni/libzrtp/sources/COPYING
index 4432540..02bbb60 100644
--- a/jni/libzrtp/sources/COPYING
+++ b/jni/libzrtp/sources/COPYING
@@ -1,676 +1,165 @@
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
+ GNU LESSER 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
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
+ 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 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.
+ 0. Additional Definitions.
- 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.
+ 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.
- 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.
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
- 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.
+ 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.
- 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.
+ 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".
- 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 "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.
- 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.
+ 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.
- 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.
+ 1. Exception to Section 3 of the GNU GPL.
- The precise terms and conditions for copying, distribution and
-modification follow.
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
- TERMS AND CONDITIONS
+ 2. Conveying Modified Versions.
- 0. Definitions.
+ 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:
- "This License" refers to version 3 of the GNU General Public License.
+ 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
- "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.
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
- 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.
+ 3. Object Code Incorporating Material from Library Header Files.
- A "covered work" means either the unmodified Program or a work based
-on the Program.
+ 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:
- 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.
+ 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 "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.
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
- 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.
+ 4. Combined Works.
- 1. Source Code.
+ 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:
- 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.
+ 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.
- 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.
+ b) Accompany the Combined Work with a copy 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.
+ 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 "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.
+ d) Do one of the following:
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
+ 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 for a work in source code form is that
-same work.
+ 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.
- 2. Basic Permissions.
+ 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.)
- 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.
+ 5. Combined Libraries.
- 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.
+ 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:
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
+ 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.
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+ 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.
- 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.
+ 6. Revised Versions of the GNU Lesser General Public License.
- 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.
+ 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.
- 4. Conveying Verbatim Copies.
+ 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.
- 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>.
-
+ 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
diff --git a/jni/libzrtp/sources/NEWS b/jni/libzrtp/sources/NEWS
index 6224923..f2b72e6 100755
--- a/jni/libzrtp/sources/NEWS
+++ b/jni/libzrtp/sources/NEWS
@@ -1,3 +1,128 @@
+== 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
@@ -150,7 +275,7 @@
The method ''setOtherSecret(...)'' was renamed to ''setPbxSecret(...)''
to reflect the modification in the draft.
-The methos ''setSrtpsSecret(...)'' is was renamed to ''setAuxSecret(...)''
+The method ''setSrtpsSecret(...)'' 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 cac0592..f7b9966 100644
--- a/jni/libzrtp/sources/README.md
+++ b/jni/libzrtp/sources/README.md
@@ -1,29 +1,49 @@
## GNU ZRTP C++
This package provides a library that adds ZRTP support to the GNU
-ccRTP stack. Phil Zimmermann developed ZRTP to allow ad-hoc, easy to
+ccRTP stack and serves as library for other RTP stacks (PJSIP, GStreamer).
+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][]. Currently GNU ZRTP
-C++ supports the following features:
+The GNU ZRTP implementation is compliant to [RFC 6189][] and adds some more
+algorithms. Currently GNU ZRTP C++ supports the following features:
* multi-stream mode
-* 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
+* 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
* 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)
+ characters) and the SAS 256 type using words.
-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).
+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`.
### Interoperability
During the development of ZRTP and its sister implementation ZRTP4J (the Java
@@ -48,7 +68,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 use this feature is
+based clients to use ZRTP. One of the first clients that uses this feature is
*[CSipSimple][]*, an very good open source Android SIP client.
[pjsip]: http://www.pjsip.org
@@ -71,13 +91,21 @@
### License and further information
-Please note, this library is licensed under the GNU GPL, version 3 or
-later, and has been copyright assigned to the Free Software Foundation.
+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.
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
@@ -89,11 +117,23 @@
the source archive or pulled the source from [Github][]:
cd <zrtpsrc_dir>
- mkdir build
- cd build
- cmake ..
- make
-
+ 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.
+
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`,
@@ -103,3 +143,13 @@
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.h b/jni/libzrtp/sources/bnlib/bn.h
index f4dedfc..5cc80f0 100644
--- a/jni/libzrtp/sources/bnlib/bn.h
+++ b/jni/libzrtp/sources/bnlib/bn.h
@@ -30,6 +30,7 @@
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
@@ -226,6 +227,7 @@
struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
struct BigNum const *mod);
+#endif /* SWIF */
#ifdef __cplusplus
}
diff --git a/jni/libzrtp/sources/bnlib/bn32.c b/jni/libzrtp/sources/bnlib/bn32.c
index b0a3b85..ee0d257 100644
--- a/jni/libzrtp/sources/bnlib/bn32.c
+++ b/jni/libzrtp/sources/bnlib/bn32.c
@@ -13,7 +13,7 @@
#define HAVE_CONFIG_H 0
#endif
#if HAVE_CONFIG_H
-#include "bnconfig.h"
+#include <bnconfig.h>
#endif
/*
diff --git a/jni/libzrtp/sources/bnlib/bn64.c b/jni/libzrtp/sources/bnlib/bn64.c
index 6cb98ba..23cf185 100644
--- a/jni/libzrtp/sources/bnlib/bn64.c
+++ b/jni/libzrtp/sources/bnlib/bn64.c
@@ -13,7 +13,7 @@
#define HAVE_CONFIG_H 0
#endif
#if HAVE_CONFIG_H
-#include "bnconfig.h"
+#include <bnconfig.h>
#endif
/*
diff --git a/jni/libzrtp/sources/bnlib/bnprint.c b/jni/libzrtp/sources/bnlib/bnprint.c
index 080e4a8..a407248 100644
--- a/jni/libzrtp/sources/bnlib/bnprint.c
+++ b/jni/libzrtp/sources/bnlib/bnprint.c
@@ -112,12 +112,7 @@
getAsciiDigit(&d, radix, s[i]);
bnMulQ(X, X, radix);
- if(!neg ) {
- bnAddQ(X, d);
- }
- else {
- bnSubQ(X, d );
- }
+ bnAddQ(X, d);
}
- return( 0 );
+ return(neg);
}
diff --git a/jni/libzrtp/sources/bnlib/bnprint.h b/jni/libzrtp/sources/bnlib/bnprint.h
index 38830fb..b10393a 100644
--- a/jni/libzrtp/sources/bnlib/bnprint.h
+++ b/jni/libzrtp/sources/bnlib/bnprint.h
@@ -10,11 +10,13 @@
struct BigNum;
+#ifndef SWIG
int bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
char const *suffix);
+#endif
/**
- * Convert and ASCII string into a BigNum.
+ * 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.
diff --git a/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c b/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
new file mode 100644
index 0000000..de11280
--- /dev/null
+++ b/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
@@ -0,0 +1,731 @@
+/* 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
index 1f4123a..18e612f 100644
--- a/jni/libzrtp/sources/bnlib/ec/ec.c
+++ b/jni/libzrtp/sources/bnlib/ec/ec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Werner Dittmann
+ * 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>
@@ -100,6 +100,46 @@
"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 */
/*============================================================================*/
@@ -140,53 +180,90 @@
return 0;
}
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod)
+int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve)
{
bnMul (rslt, n1, n2);
- bnMod (rslt, rslt, mod);
+ 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)
+int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve)
{
bnMulQ (rslt, n1, n2);
- bnMod (rslt, rslt, mod);
- return 0;
+ 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)
+int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve)
{
bnSquare (rslt, n1);
- bnMod (rslt, rslt, mod);
+ if (curve)
+ curve->modOp(rslt, rslt, mod);
+ else
+ bnMod(rslt, rslt, mod);
return 0;
}
-int ecGetCurveNistECp(NistCurves curveId, NistECpCurve *curve)
+/*
+ * 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()
{
- size_t maxBits;
- curveData *cd;
+ 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);
+}
- if (!initialized) {
- 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);
- 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;
-
+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;
@@ -196,41 +273,11 @@
bnBegin(&curve->_t1); curve->t1 = &curve->_t1;
bnBegin(&curve->_t2); curve->t2 = &curve->_t2;
bnBegin(&curve->_t3); curve->t3 = &curve->_t3;
+}
- switch (curveId) {
- case NIST192P:
- cd = &nist192;
- break;
-
- case NIST224P:
- cd = &nist224;
- break;
-
- case NIST256P:
- cd = &nist256;
- break;
-
- case NIST384P:
- cd = &nist384;
- break;
-
- case NIST521P:
- cd = &nist521;
- break;
-
- default:
- return -2;
- }
-
- 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);
+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;
@@ -245,16 +292,151 @@
bnPrealloc(curve->t1, maxBits);
bnPrealloc(curve->t2, maxBits);
bnPrealloc(curve->t3, maxBits);
-
- return 0;
-
-/* ecFreeCurveNistECp(curve);
- return ret;
-*/
}
+int ecGetCurveNistECp(Curves curveId, EcCurve *curve)
+{
+ curveData *cd;
-void ecFreeCurveNistECp(NistECpCurve *curve)
+ 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;
@@ -277,12 +459,40 @@
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 NistECpCurve *curve, EcPoint *R, const EcPoint *P)
+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;
@@ -292,13 +502,13 @@
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); /* z_2 = Z^(-2) */
- bnMulMod_(R->x, P->x, &z_2, curve->p);
-
+ 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); /* z_2 = Z^(-3) */
- bnMulMod_(R->y, P->y, &z_2, curve->p);
+ 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);
@@ -307,7 +517,48 @@
return ret;
}
-int ecDoublePoint(const NistECpCurve *curve, EcPoint *R, const EcPoint *P)
+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;
@@ -333,37 +584,37 @@
ptP = P;
/* S = 4*X*Y^2, save Y^2 in t1 for later use */
- bnMulMod_(curve->t1, ptP->y, ptP->y, curve->p); /* t1 = Y^2 */
- bnMulMod_(curve->t0, ptP->x, mpiFour, curve->p); /* t0 = 4 * X */
- bnMulMod_(curve->S1, curve->t0, curve->t1, curve->p); /* S1 = t0 * t1 */
+ 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); /* t2 = Z^2 */
+ 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); /* t3 = 3 * t0 */
+ 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); /* M = t3 * t0 */
+ 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); /* t2 = M^2 */
- bnMulMod_(curve->t0, curve->S1, mpiTwo, curve->p); /* t0 = S * 2 */
+ 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 */
+ 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); /* t3 = Y^4 (t1 saved above) */
- bnMulMod_(curve->t2, curve->t3, mpiEight, curve->p); /* t2 = t3 * 8 */
+ 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); /* t0 = M * t3 */
+ 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 */
+ bnSubMod_(R->y, curve->t2, curve->p); /* Y' = t0 - t2 */
/* Z' = 2*Y*Z */
- bnMulMod_(curve->t0, ptP->y, mpiTwo, curve->p); /* t0 = 2 * Y */
- bnMulMod_(R->z, curve->t0, ptP->z, curve->p); /* Z' = to * 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);
@@ -371,8 +622,72 @@
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 NistECpCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
+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;
@@ -424,23 +739,23 @@
ptQ = Q;
/* U1 = X1*Z2^2, where X1: P->x, Z2: Q->z */
- bnMulMod_(curve->t1, ptQ->z, ptQ->z, curve->p); /* t1 = Z2^2 */
- bnMulMod_(curve->U1, ptP->x, curve->t1, curve->p); /* U1 = X1 * z_2 */
+ 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); /* t1 = Z2^3 */
- bnMulMod_(curve->S1, ptP->y, curve->t1, curve->p); /* S1 = Y1 * z_2 */
+ 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); /* t1 = Z1^2 */
- bnMulMod_(curve->H, ptQ->x, curve->t1, curve->p); /* H = X2 * t1 (store U2 in H) */
+ 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); /* t1 = Z1^3 */
- bnMulMod_(curve->R, ptQ->y, curve->t1, curve->p); /* R = Y2 * t1 (store S2 in R) */
+ 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);
@@ -458,26 +773,26 @@
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); /* t0 = H^2 */
- bnMulMod_(curve->t1, curve->U1, curve->t0, curve->p); /* t1 = U1 * t0, (hold t1) */
- bnMulMod_(curve->t0, curve->t0, curve->H, curve->p); /* t0 = H^3, (hold t0) */
- bnMulMod_(curve->t2, curve->R, curve->R, curve->p); /* t2 = R^2 */
+ 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); /* t2 = 2 * t1 */
+ 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 */
+ 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); /* t2 = R * z_2 */
- bnMulMod_(curve->S1, curve->S1, curve->t0, curve->p); /* S1 = S1 * t0, (t0 has H^3) */
+ 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 */
+ 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); /* t2 = H * Z1 */
- bnMulMod_(R->z, curve->t2, Q->z, curve->p); /* Z3 = t2 * Z2 */
+ 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);
@@ -486,10 +801,117 @@
return ret;
}
-int ecMulPointScalar(const NistECpCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
+/*
+ * 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;
- /* MPI_CHK below macro requires a 'ret' variable and a cleanup label */
+ /* 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);
@@ -515,7 +937,26 @@
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.
*
@@ -523,10 +964,15 @@
*/
static int _random(unsigned char *output, size_t len)
{
- size_t i;
+ size_t num = 0;
- for(i = 0; i < len; ++i )
- output[i] = random();
+ int rnd = open("/dev/urandom", O_RDONLY);
+ if (rnd >= 0) {
+ num = read(rnd, output, len);
+ close(rnd);
+ }
+ else
+ return num;
return( 0 );
}
@@ -538,7 +984,12 @@
}
#endif
-int ecGenerateRandomNumber(const NistECpCurve *curve, BigNum *d)
+int ecGenerateRandomNumber(const EcCurve *curve, BigNum *d)
+{
+ return curve->randomOp(curve, d);
+}
+
+static int ecGenerateRandomNumberNist(const EcCurve *curve, BigNum *d)
{
BigNum c, nMinusOne;
@@ -568,3 +1019,677 @@
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
index b1bb47c..172ffd8 100644
--- a/jni/libzrtp/sources/bnlib/ec/ec.h
+++ b/jni/libzrtp/sources/bnlib/ec/ec.h
@@ -29,18 +29,34 @@
NIST224P = 2,
NIST256P = 3,
NIST384P = 4,
- NIST521P = 5
-} NistCurves;
+ NIST521P = 5,
+ Curve25519 = 10,
+ Curve3617 = 11
+} Curves;
/**
- * @brief This structure contains the value of NIST EC curves over Prime Fields.
- *
- * The <b>a</b> curve parameter is the constant -3 and is computed during initialization
- * of the curve structure.
- *
- * The field names correspond to the variable names defined in NIST FIPS 186-3, E.1.2
+ * \brief This structure contains the x, y affine coordinates and the z value if we
+ * use projective coordinates during EC point arithmetic.
*/
-typedef struct {
+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;
@@ -62,16 +78,18 @@
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;
-} NistECpCurve;
+ 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);
-/**
- * \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;
+};
+
+typedef struct EcCurve EcCurve;
+typedef EcCurve NistECpCurve;
/**
* \brief Marco to initialize a EC point structure.
@@ -94,7 +112,16 @@
*
* \param P Address of the EC point structure.
*/
-#define SET_EC_BASE_POINT(C, P) {EcPoint *e = P; const NistECpCurve *c = C; bnCopy(e->x, c->Gx); bnCopy(e->y, c->Gy); bnSetQ(e->z, 1);}
+#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.
@@ -104,23 +131,23 @@
*
* \param curveId Which curve to initialize
*
- * \param curve Pointer to a NistECpCurve structure
+ * \param curve Pointer to a EcCurve structure
*
- * \return 0 if successful, or a POLARSSL_ERR_EC_XXX/ POLARSSL_ERR_MPI_XXX error code.
+ * \return 0 if successful
*
* \note Call ecFreeCurveNistECp to return allocated memory.
*/
-int ecGetCurveNistECp(NistCurves curveId, NistECpCurve *curve);
+int ecGetCurveNistECp(Curves curveId, NistECpCurve *curve);
/**
- * \brief Free NIST EC curve parameters.
+ * \brief Free EC curve parameters.
*
- * \param curve Pointer to a NistECpCurve structure
+ * \param curve Pointer to a EcCurve structure
*
* \note Curve parameters must be initialized calling ecGetCurveNistECp.
*/
-void ecFreeCurveNistECp(NistECpCurve *curve);
+void ecFreeCurveNistECp(EcCurve *curve);
/**
* \brief Double an EC point.
@@ -129,13 +156,13 @@
* further reference see RFC 6090 or the standard work <i>Guide to Elliptic
* Curve Cryptography</i>.
*
- * \param curve Address of Nist EC curve structure
+ * \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, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
+ * \return 0 if successful
*/
-int ecDoublePoint(const NistECpCurve *curve, EcPoint *R, const EcPoint *P);
+int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P);
/**
* \brief Add two EC points.
@@ -144,43 +171,43 @@
* further reference see RFC 6090 or the standard work <i>Guide to Elliptic
* Curve Cryptography</i>.
*
- * \param curve Address of Nist EC curve structure
+ * \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, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
+ * \return 0 if successful
*/
-int ecAddPoint(const NistECpCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
+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 Nist EC curve structure
+ * \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, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
+ * \return 0 if successful
*/
-int ecMulPointScalar(const NistECpCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
+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 Nist EC curve structure
+ * \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, or a POLARSSL_ERR_EC_XXX / POLARSSL_ERR_MPI_XXX error code.
+ * \return 0 if successful
*/
-int ecGetAffine(const NistECpCurve *curve, EcPoint *R, const EcPoint *P);
+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 to generate a ECDH public key.
+ * Use this number as ECDH private key.
*
* @param curve the NIST curve to use.
*
@@ -188,6 +215,35 @@
*/
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
*/
@@ -199,11 +255,11 @@
int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, 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);
+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);
+int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve);
#ifdef __cplusplus
}
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.c b/jni/libzrtp/sources/bnlib/ec/ecdh.c
index 25ea8cd..8d1bc23 100644
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.c
+++ b/jni/libzrtp/sources/bnlib/ec/ecdh.c
@@ -9,7 +9,7 @@
#include <ec/ec.h>
#include <ec/ecdh.h>
-int ecdhGeneratePublic(const NistECpCurve *curve, EcPoint *Q, const BigNum *d)
+int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d)
{
EcPoint G;
@@ -21,10 +21,10 @@
FREE_EC_POINT(&G);
- return 0;
+ return ecCheckPubKey(curve, Q);
}
-int ecdhComputeAgreement(const NistECpCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d)
+int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d)
{
EcPoint t0;
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.h b/jni/libzrtp/sources/bnlib/ec/ecdh.h
index 0cf083a..7ec32ad 100644
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.h
+++ b/jni/libzrtp/sources/bnlib/ec/ecdh.h
@@ -22,15 +22,17 @@
/**
* @brief Takes a secret large random number and computes the public EC point.
*
- * @param curve is the NIST curve to use.
+ * @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 NistECpCurve *curve, EcPoint *Q, const BigNum *d);
+int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d);
/**
* @brief Computes the key agreement value.
@@ -38,7 +40,7 @@
* Takes the public EC point of the other party and applies the EC DH algorithm
* to compute the agreed value.
*
- * @param curve is the NIST curve to use, must be the same curve as used in
+ * @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.
@@ -47,7 +49,7 @@
*
* @param d is the secret random number.
*/
-int ecdhComputeAgreement(const NistECpCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d);
+int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d);
#ifdef __cplusplus
}
diff --git a/jni/libzrtp/sources/bnlib/lbn32.c b/jni/libzrtp/sources/bnlib/lbn32.c
index 831b25c..73fedcb 100644
--- a/jni/libzrtp/sources/bnlib/lbn32.c
+++ b/jni/libzrtp/sources/bnlib/lbn32.c
@@ -69,7 +69,7 @@
#define HAVE_CONFIG_H 0
#endif
#if HAVE_CONFIG_H
-#include "bnconfig.h"
+#include <bnconfig.h>
#endif
/*
diff --git a/jni/libzrtp/sources/bnlib/lbn64.c b/jni/libzrtp/sources/bnlib/lbn64.c
index f14deea..e930652 100644
--- a/jni/libzrtp/sources/bnlib/lbn64.c
+++ b/jni/libzrtp/sources/bnlib/lbn64.c
@@ -69,7 +69,7 @@
#define HAVE_CONFIG_H 0
#endif
#if HAVE_CONFIG_H
-#include "bnconfig.h"
+#include <bnconfig.h>
#endif
/*
diff --git a/jni/libzrtp/sources/clients/ccrtp/CMakeLists.txt b/jni/libzrtp/sources/clients/ccrtp/CMakeLists.txt
deleted file mode 100755
index aee4b24..0000000
--- a/jni/libzrtp/sources/clients/ccrtp/CMakeLists.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-
-# 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})
-
-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})
-
-#to make sure includes are first taken - it contains config.h
-include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../srtp ${CMAKE_CURRENT_SOURCE_DIR}/../../bnlib)
-
-# **** setup the various crypto interface implementations ***
-# Twofish is a special case: its always a standalone modlue and thus
-# not specific to a library.
-# NOTE: the standalone modules live in the 'crypto'
-if (OPENSSL_FOUND)
- set(crypto_src
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/zrtpDH.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/hmac256.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/sha256.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/hmac384.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/sha384.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/aesCFB.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/openssl/InitializeOpenSSL.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/crypto/twoCFB.cpp)
-endif()
-
-if (CRYPTO_STANDALONE)
- set(crypto_src
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/ZrtpRandom.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../common/Thread.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../common/MutexClass.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/../../common/EventClass.cpp
- ${zrtp_crypto_src} ${bnlib_src})
-endif()
-
-set(cryptcommon_srcs
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/twofish.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/twofish_cfb.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/aescrypt.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/aeskey.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/aestab.c
- ${CMAKE_CURRENT_SOURCE_DIR}/../../cryptcommon/aes_modes.c)
-
-set(zrtp_ccrtp_src
- ${CMAKE_CURRENT_SOURCE_DIR}/ZrtpQueue.cpp)
-
-set(zrtpcpp_src ${zrtp_src} ${zrtp_ccrtp_src} ${crypto_src} ${cryptcommon_srcs})
-
-if(BUILD_STATIC AND NOT BUILD_SHARED)
- set(LIBRARY_BUILD_TYPE STATIC)
-else()
- set(LIBRARY_BUILD_TYPE SHARED)
-endif()
-
-add_library(${zrtplibName} ${LIBRARY_BUILD_TYPE} ${zrtpcpp_src})
-set_target_properties(${zrtplibName} PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION})
-target_link_libraries(${zrtplibName} ${LIBS})
-
-add_dependencies(${zrtplibName} ccrtp)
-
-# **** Setup packing environment ****
-#
-if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
- include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Modules/GeneratePackage.cmake)
-
- GENERATE_PACKAGING(${PACKAGE} ${VERSION})
-endif()
-
-# **** Create the external files for RPM and pkgconfig ****
-#
-set(prefix ${CMAKE_INSTALL_PREFIX})
-set(exec_prefix ${prefix}/bin)
-set(libdir ${prefix}/${LIBDIRNAME})
-set(includedir ${prefix}/include)
-set(PACKAGE pkgconfig)
-
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../libzrtpcpp.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplibName}.pc @ONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../libzrtpcpp.spec.cmake ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplibName}.spec @ONLY)
-
-# **** install files ****
-#
-set(ccrtp_inst
- ${CMAKE_CURRENT_SOURCE_DIR}/ZrtpQueue.h
- ${CMAKE_CURRENT_SOURCE_DIR}/zrtpccrtp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/CcrtpTimeoutProvider.h)
-
-install(FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/libzrtpcpp/ZrtpCodes.h
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/libzrtpcpp/ZrtpConfigure.h
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/libzrtpcpp/ZrtpCallback.h
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/libzrtpcpp/ZrtpCWrapper.h
- ${CMAKE_CURRENT_SOURCE_DIR}/../../zrtp/libzrtpcpp/ZrtpUserCallback.h ${ccrtp_inst} DESTINATION include/libzrtpcpp)
-
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplibName}.pc DESTINATION ${LIBDIRNAME}/pkgconfig)
-
-install(TARGETS ${zrtplibName} DESTINATION ${LIBDIRNAME})
-
-if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
-
- ########### Add uninstall target ###############
- configure_file("${CMAKE_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()
-
-
diff --git a/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.cpp b/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.cpp
deleted file mode 100644
index 9e838da..0000000
--- a/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.cpp
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- 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 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 <string>
-#include <stdio.h>
-
-#include <ZrtpQueue.h>
-#include <libzrtpcpp/ZIDCache.h>
-#include <libzrtpcpp/ZRtp.h>
-#include <libzrtpcpp/ZrtpStateClass.h>
-#include <libzrtpcpp/ZrtpUserCallback.h>
-
-static TimeoutProvider<std::string, ost::ZrtpQueue*>* staticTimeoutProvider = NULL;
-
-NAMESPACE_COMMONCPP
-using namespace GnuZrtpCodes;
-
-ZrtpQueue::ZrtpQueue(uint32 size, RTPApplication& app) :
- AVPQueue(size,app)
-{
- init();
-}
-
-ZrtpQueue::ZrtpQueue(uint32 ssrc, uint32 size, RTPApplication& app) :
- AVPQueue(ssrc,size,app)
-{
- init();
-}
-
-void ZrtpQueue::init()
-{
- zrtpUserCallback = NULL;
- enableZrtp = false;
- started = false;
- mitmMode = false;
- enableParanoidMode = false;
- zrtpEngine = NULL;
- senderZrtpSeqNo = 1;
-
- clientIdString = clientId;
- peerSSRC = 0;
-}
-
-ZrtpQueue::~ZrtpQueue() {
-
- endQueue();
- stopZrtp();
-
- if (zrtpUserCallback != NULL) {
- delete zrtpUserCallback;
- zrtpUserCallback = NULL;
- }
-}
-
-int32_t
-ZrtpQueue::initialize(const char *zidFilename, bool autoEnable, ZrtpConfigure* config)
-{
- int32_t ret = 1;
-
- synchEnter();
-
- ZrtpConfigure* configOwn = NULL;
- if (config == NULL) {
- config = configOwn = new ZrtpConfigure();
- config->setStandardConfig();
- }
- enableZrtp = autoEnable;
-
- config->setParanoidMode(enableParanoidMode);
-
- if (staticTimeoutProvider == NULL) {
- staticTimeoutProvider = new TimeoutProvider<std::string, ZrtpQueue*>();
- staticTimeoutProvider->start();
- }
- ZIDCache* zf = getZidCacheInstance();
- if (!zf->isOpen()) {
- std::string fname;
- if (zidFilename == NULL) {
- char *home = getenv("HOME");
- std::string baseDir = (home != NULL) ? (std::string(home) + std::string("/."))
- : std::string(".");
- fname = baseDir + std::string("GNUZRTP.zid");
- zidFilename = fname.c_str();
- }
- if (zf->open((char *)zidFilename) < 0) {
- enableZrtp = false;
- ret = -1;
- }
- }
- if (ret > 0) {
- const uint8_t* ownZid = zf->getZid();
- zrtpEngine = new ZRtp((uint8_t*)ownZid, (ZrtpCallback*)this, clientIdString, config, mitmMode, signSas);
- }
- if (configOwn != NULL) {
- delete configOwn;
- }
- synchLeave();
- return ret;
-}
-
-void ZrtpQueue::startZrtp() {
- if (zrtpEngine != NULL) {
- zrtpEngine->startZrtpEngine();
- started = true;
- }
-}
-
-void ZrtpQueue::stopZrtp() {
- if (zrtpEngine != NULL) {
- delete zrtpEngine;
- zrtpEngine = NULL;
- started = false;
- }
-}
-
-/*
- * The takeInDataPacket implementation for ZRTPQueue.
- */
-size_t
-ZrtpQueue::takeInDataPacket(void)
-{
- InetHostAddress network_address;
- tpport_t transport_port;
-
- uint32 nextSize = (uint32)getNextDataPacketSize();
- unsigned char* buffer = new unsigned char[nextSize];
- int32 rtn = (int32)recvData(buffer, nextSize, network_address, transport_port);
- if ( (rtn < 0) || ((uint32)rtn > getMaxRecvPacketSize()) ){
- delete buffer;
- return 0;
- }
-
- IncomingZRTPPkt* packet = NULL;
- // check if this could be a real RTP/SRTP packet.
- if ((*buffer & 0xf0) != 0x10) {
- return (rtpDataPacket(buffer, rtn, network_address, transport_port));
- }
-
- // We assume all other packets are ZRTP packets here. Process
- // if ZRTP processing is enabled. Because valid RTP packets are
- // already handled we delete any packets here after processing.
- if (enableZrtp && zrtpEngine != NULL) {
- // 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);
- crc = ntohl(crc);
-
- if (!zrtpCheckCksum(buffer, temp, crc)) {
- delete buffer;
- if (zrtpUserCallback != NULL)
- zrtpUserCallback->showMessage(Warning, WarningCRCmismatch);
- return 0;
- }
-
- packet = new IncomingZRTPPkt(buffer,rtn);
-
- uint32 magic = packet->getZrtpMagic();
-
- // Check if it is really a ZRTP packet, if not delete it and return 0
- if (magic != ZRTP_MAGIC || zrtpEngine == NULL) {
- delete packet;
- return 0;
- }
- // cover the case if the other party sends _only_ ZRTP packets at the
- // beginning of a session. Start ZRTP in this case as well.
- if (!started) {
- startZrtp();
- }
- // this now points beyond the undefined and length field.
- // We need them, thus adjust
- unsigned char* extHeader =
- const_cast<unsigned char*>(packet->getHdrExtContent());
- extHeader -= 4;
-
- // store peer's SSRC, used when creating the CryptoContext
- peerSSRC = packet->getSSRC();
- zrtpEngine->processZrtpMessage(extHeader, peerSSRC, rtn);
- }
- delete packet;
- return 0;
-}
-
-size_t
-ZrtpQueue::rtpDataPacket(unsigned char* buffer, int32 rtn, InetHostAddress network_address, tpport_t transport_port)
-{
- // Special handling of padding to take care of encrypted content.
- // In case of SRTP the padding length field is also encrypted, thus
- // it gives a wrong length. Check and clear padding bit before
- // creating the RTPPacket. Will be set and re-computed after a possible
- // SRTP decryption.
- uint8 padSet = (*buffer & 0x20);
- if (padSet) {
- *buffer = *buffer & ~0x20; // clear padding bit
- }
- // build a packet. It will link itself to its source
- IncomingRTPPkt* packet =
- new IncomingRTPPkt(buffer,rtn);
-
- // Generic header validity check.
- if ( !packet->isHeaderValid() ) {
- delete packet;
- return 0;
- }
-
- // Look for a CryptoContext for this packet's SSRC
- CryptoContext* pcc = getInQueueCryptoContext(packet->getSSRC());
-
- // If no crypto context is available for this SSRC but we are already in
- // Secure state then create a CryptoContext for this SSRC.
- // Assumption: every SSRC stream sent via this connection is secured
- // _and_ uses the same crypto parameters.
- if (pcc == NULL) {
- pcc = getInQueueCryptoContext(0);
- if (pcc != NULL) {
- pcc = pcc->newCryptoContextForSSRC(packet->getSSRC(), 0, 0L);
- if (pcc != NULL) {
- pcc->deriveSrtpKeys(0);
- setInQueueCryptoContext(pcc);
- }
- }
- }
- // If no crypto context: then either ZRTP is off or in early state
- // If crypto context is available then unprotect data here. If an error
- // occurs report the error and discard the packet.
- if (pcc != NULL) {
- int32 ret;
- if ((ret = packet->unprotect(pcc)) < 0) {
- if (!onSRTPPacketError(*packet, ret)) {
- delete packet;
- return 0;
- }
- }
- if (started && zrtpEngine->inState(WaitConfAck)) {
- zrtpEngine->conf2AckSecure();
- }
- }
-
- // virtual for profile-specific validation and processing.
- if (!onRTPPacketRecv(*packet) ) {
- delete packet;
- return 0;
- }
- if (padSet) {
- packet->reComputePayLength(true);
- }
- // get time of arrival
- struct timeval recvtime;
- gettimeofday(&recvtime,NULL);
-
- bool source_created;
- SyncSourceLink* sourceLink =
- getSourceBySSRC(packet->getSSRC(),source_created);
- SyncSource* s = sourceLink->getSource();
- if ( source_created ) {
- // Set data transport address.
- setDataTransportPort(*s,transport_port);
- // Network address is assumed to be the same as the control one
- setNetworkAddress(*s,network_address);
- sourceLink->initStats();
- // First packet arrival time.
- sourceLink->setInitialDataTime(recvtime);
- sourceLink->setProbation(getMinValidPacketSequence());
- if ( sourceLink->getHello() )
- onNewSyncSource(*s);
- }
- else if ( 0 == s->getDataTransportPort() ) {
- // Test if RTCP packets had been received but this is the
- // first data packet from this source.
- setDataTransportPort(*s,transport_port);
- }
-
- // Before inserting in the queue,
- // 1) check for collisions and loops. If the packet cannot be
- // assigned to a source, it will be rejected.
- // 2) check the source is a sufficiently well known source
- // TODO: also check CSRC identifiers.
- if (checkSSRCInIncomingRTPPkt(*sourceLink, source_created,
- network_address, transport_port) &&
- recordReception(*sourceLink,*packet,recvtime) ) {
- // now the packet link is linked in the queues
- IncomingRTPPktLink* packetLink = new IncomingRTPPktLink(packet, sourceLink, recvtime,
- packet->getTimestamp() - sourceLink->getInitialDataTimestamp(),
- NULL,NULL,NULL,NULL);
- insertRecvPacket(packetLink);
- } else {
- // must be discarded due to collision or loop or
- // invalid source
- delete packet;
- return 0;
- }
- // Start the ZRTP engine after we got a at least one RTP packet and
- // sent some as well or we are in multi-stream mode.
- if (!started && enableZrtp) {
- startZrtp();
- }
- return rtn;
-}
-
-bool
-ZrtpQueue::onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode)
-{
- if (errorCode == -1) {
- sendInfo(Warning, WarningSRTPauthError);
- }
- else {
- sendInfo(Warning, WarningSRTPreplayError);
- }
- return false;
-}
-
-
-void
-ZrtpQueue::putData(uint32 stamp, const unsigned char* data, size_t len)
-{
- OutgoingDataQueue::putData(stamp, data, len);
-}
-
-
-void
-ZrtpQueue::sendImmediate(uint32 stamp, const unsigned char* data, size_t len)
-{
- OutgoingDataQueue::sendImmediate(stamp, data, len);
-}
-
-
-/*
- * Here the callback methods required by the ZRTP implementation
- */
-int32_t ZrtpQueue::sendDataZRTP(const unsigned char *data, int32_t length) {
-
- OutgoingZRTPPkt* packet = new OutgoingZRTPPkt(data, length);
-
- packet->setSSRC(getLocalSSRC());
-
- packet->setSeqNum(senderZrtpSeqNo++);
-
- /*
- * Compute the ZRTP CRC over the full ZRTP packet. Thus include
- * the fixed packet header into the calculation.
- */
- uint16_t temp = packet->getRawPacketSize() - CRC_SIZE;
- uint8_t* pt = (uint8_t*)packet->getRawPacket();
- uint32_t crc = zrtpGenerateCksum(pt, temp);
- // convert and store CRC in crc field of ZRTP packet.
- crc = zrtpEndCksum(crc);
-
- // advance pointer to CRC storage
- pt += temp;
- *(uint32_t*)pt = htonl(crc);
-
- dispatchImmediate(packet);
- delete packet;
-
- return 1;
-}
-
-bool ZrtpQueue::srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part)
-{
- CryptoContext* recvCryptoContext;
- CryptoContext* senderCryptoContext;
- CryptoContextCtrl* recvCryptoContextCtrl;
- CryptoContextCtrl* senderCryptoContextCtrl;
-
- int cipher;
- int authn;
- int authKeyLen;
-
- if (secrets->authAlgorithm == Sha1) {
- authn = SrtpAuthenticationSha1Hmac;
- authKeyLen = 20;
- }
-
- if (secrets->authAlgorithm == Skein) {
- authn = SrtpAuthenticationSkeinHmac;
- authKeyLen = 32;
- }
-
- if (secrets->symEncAlgorithm == Aes)
- cipher = SrtpEncryptionAESCM;
-
- if (secrets->symEncAlgorithm == TwoFish)
- cipher = SrtpEncryptionTWOCM;
-
- if (part == ForSender) {
- // To encrypt packets: intiator uses initiator keys,
- // responder uses responder keys
- // Create a "half baked" crypto context first and store it. This is
- // the main crypto context for the sending part of the connection.
- if (secrets->role == Initiator) {
- senderCryptoContext = new CryptoContext(
- 0,
- 0,
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- (unsigned char*)secrets->keyInitiator, // Master Key
- secrets->initKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltInitiator, // Master Salt
- secrets->initSaltLen / 8, // Master Salt length
- secrets->initKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->initSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag lenA
- senderCryptoContextCtrl = new CryptoContextCtrl(0,
- cipher, // encryption algo
- authn, // authtication algo
- (unsigned char*)secrets->keyInitiator, // Master Key
- secrets->initKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltInitiator, // Master Salt
- secrets->initSaltLen / 8, // Master Salt length
- secrets->initKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->initSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- }
- else {
- senderCryptoContext = new CryptoContext(
- 0,
- 0,
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- (unsigned char*)secrets->keyResponder, // Master Key
- secrets->respKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltResponder, // Master Salt
- secrets->respSaltLen / 8, // Master Salt length
- secrets->respKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->respSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- senderCryptoContextCtrl = new CryptoContextCtrl(0,
- cipher, // encryption algo
- authn, // authtication algo
- (unsigned char*)secrets->keyResponder, // Master Key
- secrets->respKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltResponder, // Master Salt
- secrets->respSaltLen / 8, // Master Salt length
- secrets->respKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->respSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- }
- if (senderCryptoContext == NULL) {
- return false;
- }
- // Insert the Crypto templates (SSRC == 0) into the queue. When we send
- // the first RTP or RTCP packet the real crypto context will be created.
- // Refer to putData(), sendImmediate() in ccrtp's outqueue.cpp and
- // takeinControlPacket() in ccrtp's control.cpp.
- //
- setOutQueueCryptoContext(senderCryptoContext);
- setOutQueueCryptoContextCtrl(senderCryptoContextCtrl);
- }
- if (part == ForReceiver) {
- // To decrypt packets: intiator uses responder keys,
- // responder initiator keys
- // See comment above.
- if (secrets->role == Initiator) {
- recvCryptoContext = new CryptoContext(
- 0,
- 0,
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- (unsigned char*)secrets->keyResponder, // Master Key
- secrets->respKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltResponder, // Master Salt
- secrets->respSaltLen / 8, // Master Salt length
- secrets->respKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->respSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- recvCryptoContextCtrl = new CryptoContextCtrl(0,
- cipher, // encryption algo
- authn, // authtication algo
- (unsigned char*)secrets->keyResponder, // Master Key
- secrets->respKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltResponder, // Master Salt
- secrets->respSaltLen / 8, // Master Salt length
- secrets->respKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->respSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
-
- }
- else {
- recvCryptoContext = new CryptoContext(
- 0,
- 0,
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- (unsigned char*)secrets->keyInitiator, // Master Key
- secrets->initKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltInitiator, // Master Salt
- secrets->initSaltLen / 8, // Master Salt length
- secrets->initKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->initSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- recvCryptoContextCtrl = new CryptoContextCtrl(0,
- cipher, // encryption algo
- authn, // authtication algo
- (unsigned char*)secrets->keyInitiator, // Master Key
- secrets->initKeyLen / 8, // Master Key length
- (unsigned char*)secrets->saltInitiator, // Master Salt
- secrets->initSaltLen / 8, // Master Salt length
- secrets->initKeyLen / 8, // encryption keyl
- authKeyLen, // authentication key len
- secrets->initSaltLen / 8, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag len
- }
- if (recvCryptoContext == NULL) {
- return false;
- }
- // Insert the Crypto templates (SSRC == 0) into the queue. When we receive
- // the first RTP or RTCP packet the real crypto context will be created.
- // Refer to rtpDataPacket() above and takeinControlPacket in ccrtp's control.cpp.
- //
- setInQueueCryptoContext(recvCryptoContext);
- setInQueueCryptoContextCtrl(recvCryptoContextCtrl);
- }
- return true;
-}
-
-void ZrtpQueue::srtpSecretsOn(std::string c, std::string s, bool verified)
-{
-
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->secureOn(c);
- if (!s.empty()) {
- zrtpUserCallback->showSAS(s, verified);
- }
- }
-}
-
-void ZrtpQueue::srtpSecretsOff(EnableSecurity part) {
- if (part == ForSender) {
- removeOutQueueCryptoContext(NULL);
- removeOutQueueCryptoContextCtrl(NULL);
- }
- if (part == ForReceiver) {
- removeInQueueCryptoContext(NULL);
- removeInQueueCryptoContextCtrl(NULL);
- }
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->secureOff();
- }
-}
-
-int32_t ZrtpQueue::activateTimer(int32_t time) {
- std::string s("ZRTP");
- if (staticTimeoutProvider != NULL) {
- staticTimeoutProvider->requestTimeout(time, this, s);
- }
- return 1;
-}
-
-int32_t ZrtpQueue::cancelTimer() {
- std::string s("ZRTP");
- if (staticTimeoutProvider != NULL) {
- staticTimeoutProvider->cancelRequest(this, s);
- }
- return 1;
-}
-
-void ZrtpQueue::handleTimeout(const std::string &c) {
- if (zrtpEngine != NULL) {
- zrtpEngine->processTimeout();
- }
-}
-
-void ZrtpQueue::handleGoClear()
-{
- fprintf(stderr, "Need to process a GoClear message!");
-}
-
-void ZrtpQueue::sendInfo(MessageSeverity severity, int32_t subCode) {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->showMessage(severity, subCode);
- }
-}
-
-void ZrtpQueue::zrtpNegotiationFailed(MessageSeverity severity, int32_t subCode) {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->zrtpNegotiationFailed(severity, subCode);
- }
-}
-
-void ZrtpQueue::zrtpNotSuppOther() {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->zrtpNotSuppOther();
- }
-}
-
-void ZrtpQueue::synchEnter() {
- synchLock.enter();
-}
-
-void ZrtpQueue::synchLeave() {
- synchLock.leave();
-}
-
-void ZrtpQueue::zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info) {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->zrtpAskEnrollment(info);
- }
-}
-
-void ZrtpQueue::zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info) {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->zrtpInformEnrollment(info);
- }
-}
-
-void ZrtpQueue::signSAS(uint8_t* sasHash) {
- if (zrtpUserCallback != NULL) {
- zrtpUserCallback->signSAS(sasHash);
- }
-}
-
-bool ZrtpQueue::checkSASSignature(uint8_t* sasHash) {
- if (zrtpUserCallback != NULL) {
- return zrtpUserCallback->checkSASSignature(sasHash);
- }
- return false;
-}
-
-void ZrtpQueue::setEnableZrtp(bool onOff) {
- enableZrtp = onOff;
-}
-
-bool ZrtpQueue::isEnableZrtp() {
- return enableZrtp;
-}
-
-void ZrtpQueue::SASVerified() {
- if (zrtpEngine != NULL)
- zrtpEngine->SASVerified();
-}
-
-void ZrtpQueue::resetSASVerified() {
- if (zrtpEngine != NULL)
- zrtpEngine->resetSASVerified();
-}
-
-void ZrtpQueue::goClearOk() { }
-
-void ZrtpQueue::requestGoClear() { }
-
-void ZrtpQueue::setAuxSecret(uint8* data, int32_t length) {
- if (zrtpEngine != NULL)
- zrtpEngine->setAuxSecret(data, length);
-}
-
-void ZrtpQueue::setUserCallback(ZrtpUserCallback* ucb) {
- zrtpUserCallback = ucb;
-}
-
-void ZrtpQueue::setClientId(std::string id) {
- clientIdString = id;
-}
-
-std::string ZrtpQueue::getHelloHash() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getHelloHash();
- else
- return std::string();
-}
-
-std::string ZrtpQueue::getPeerHelloHash() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getPeerHelloHash();
- else
- return std::string();
-}
-
-std::string ZrtpQueue::getMultiStrParams() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getMultiStrParams();
- else
- return std::string();
-}
-
-void ZrtpQueue::setMultiStrParams(std::string parameters) {
- if (zrtpEngine != NULL)
- zrtpEngine->setMultiStrParams(parameters);
-}
-
-bool ZrtpQueue::isMultiStream() {
- if (zrtpEngine != NULL)
- return zrtpEngine->isMultiStream();
- return false;
-}
-
-bool ZrtpQueue::isMultiStreamAvailable() {
- if (zrtpEngine != NULL)
- return zrtpEngine->isMultiStreamAvailable();
- return false;
-}
-
-void ZrtpQueue::acceptEnrollment(bool accepted) {
- if (zrtpEngine != NULL)
- zrtpEngine->acceptEnrollment(accepted);
-}
-
-std::string ZrtpQueue::getSasType() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getSasType();
- else
- return NULL;
-}
-
-uint8_t* ZrtpQueue::getSasHash() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getSasHash();
- else
- return NULL;
-}
-
-bool ZrtpQueue::sendSASRelayPacket(uint8_t* sh, std::string render) {
-
- if (zrtpEngine != NULL)
- return zrtpEngine->sendSASRelayPacket(sh, render);
- else
- return false;
-}
-
-bool ZrtpQueue::isMitmMode() {
- return mitmMode;
-}
-
-void ZrtpQueue::setMitmMode(bool mitmMode) {
- this->mitmMode = mitmMode;
-}
-
-bool ZrtpQueue::isEnrollmentMode() {
- if (zrtpEngine != NULL)
- return zrtpEngine->isEnrollmentMode();
- else
- return false;
-}
-
-void ZrtpQueue::setEnrollmentMode(bool enrollmentMode) {
- if (zrtpEngine != NULL)
- zrtpEngine->setEnrollmentMode(enrollmentMode);
-}
-
-void ZrtpQueue::setParanoidMode(bool yesNo) {
- enableParanoidMode = yesNo;
-}
-
-bool ZrtpQueue::isParanoidMode() {
- return enableParanoidMode;
-}
-
-bool ZrtpQueue::isPeerEnrolled() {
- if (zrtpEngine != NULL)
- return zrtpEngine->isPeerEnrolled();
- else
- return false;
-}
-
-void ZrtpQueue::setSignSas(bool sasSignMode) {
- signSas = sasSignMode;
-}
-
-bool ZrtpQueue::setSignatureData(uint8* data, int32 length) {
- if (zrtpEngine != NULL)
- return zrtpEngine->setSignatureData(data, length);
- return 0;
-}
-
-const uint8* ZrtpQueue::getSignatureData() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getSignatureData();
- return 0;
-}
-
-int32 ZrtpQueue::getSignatureLength() {
- if (zrtpEngine != NULL)
- return zrtpEngine->getSignatureLength();
- return 0;
-}
-
-int32 ZrtpQueue::getPeerZid(uint8* data) {
- if (data == NULL)
- return 0;
-
- if (zrtpEngine != NULL)
- return zrtpEngine->getPeerZid(data);
-
- return 0;
-}
-
-IncomingZRTPPkt::IncomingZRTPPkt(const unsigned char* const block, size_t len) :
- IncomingRTPPkt(block,len) {
-}
-
-uint32 IncomingZRTPPkt::getZrtpMagic() const {
- return ntohl(getHeader()->timestamp);
-}
-
-uint32 IncomingZRTPPkt::getSSRC() const {
- return ntohl(getHeader()->sources[0]);
-}
-
-OutgoingZRTPPkt::OutgoingZRTPPkt(
- const unsigned char* const hdrext, uint32 hdrextlen) :
- OutgoingRTPPkt(NULL, 0, hdrext, hdrextlen, NULL ,0, 0, NULL)
-{
- getHeader()->version = 0;
- getHeader()->timestamp = htonl(ZRTP_MAGIC);
-}
-
-END_NAMESPACE
-
-/** EMACS **
- * Local variables:
- * mode: c++
- * c-default-style: ellemtel
- * c-basic-offset: 4
- * End:
- */
-
diff --git a/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.h b/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.h
deleted file mode 100644
index 7a1ee67..0000000
--- a/jni/libzrtp/sources/clients/ccrtp/ZrtpQueue.h
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- 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 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 _ZRTPQUEUE_H_
-#define _ZRTPQUEUE_H_
-
-#include <ccrtp/cqueue.h>
-#include <ccrtp/rtppkt.h>
-#include <libzrtpcpp/ZrtpCallback.h>
-#include <libzrtpcpp/ZrtpConfigure.h>
-#include <CcrtpTimeoutProvider.h>
-
-class __EXPORT ZrtpUserCallback;
-class __EXPORT ZRtp;
-
-NAMESPACE_COMMONCPP
-
-/**
- * GNU ccRTP extension to support GNU ZRTP.
- *
- * ZRTP was developed by Phil Zimmermann and provides functions to
- * negotiate keys and other necessary data (crypto data) to set-up
- * the Secure RTP (SRTP) crypto context. Refer to Phil's ZRTP
- * specification at his <a href="http://zfoneproject.com/">Zfone
- * project</a> site to get more detailed imformation about the
- * capabilities of ZRTP.
- *
- * <b>Short overview of the ZRTP implementation</b>
- *
- * ZRTP is a specific protocol to negotiate encryption algorithms
- * and the required key material. ZRTP uses a RTP session to
- * exchange its protocol messages.
- *
- * A complete GNU ZRTP implementation consists of two parts, the
- * GNU ZRTP core and specific code that binds the GNU ZRTP core to
- * the underlying RTP/SRTP stack and the operating system:
- * <ul>
- * <li>
- * The GNU ZRTP core is independent of a specific RTP/SRTP
- * stack and the operationg system and consists of the ZRTP
- * protocol state engine, the ZRTP protocol messages, and the
- * GNU ZRTP engine. The GNU ZRTP engine provides methods to
- * setup ZRTP message and to analyze received ZRTP messages,
- * to compute the crypto data required for SRTP, and to
- * maintain the required hashes and HMAC.
- * </li>
- * <li>
- * The second part of an implementation is specific
- * <em>glue</em> code the binds the GNU ZRTP core to the
- * actual RTP/SRTP implementation and other operating system
- * specific services such as timers.
- * </li>
- * </ul>
- *
- * The GNU ZRTP core uses a callback interface class (refer to
- * ZrtpCallback) to access RTP/SRTP or operating specific methods,
- * for example to send data via the RTP/SRTP stack, to access
- * timers, provide mutex handling, and to report events to the
- * application.
- *
- * <b>The ZrtpQueue</b>
- *
- * ZrtpQueue implements code that is specific to the GNU ccRTP
- * implementation. ZrtpQueue also implements the specific code to
- * provide the mutex and timeout handling to the GNU ZRTP
- * core. Both, the mutex and the timeout handling, use the GNU
- * Common C++ library to stay independent of the operating
- * seystem. For more information refer to the <a
- * href="http://www.gnutelephony.org/index.php/GNU_Common_C%2B%2B">GNU
- * Common C++</a> web site.
- *
- * To perform its tasks ZrtpQueue
- * <ul>
- * <li> extends GNU ccRTP classes to use the underlying
- * ccRTP methods and the RTP/SRTP send and receive queues
- * </li>
- * <li> implements the ZrtpCallback interface to provide ccRTP
- * access and other specific services (timer, mutex) to GNU
- * ZRTP
- * </li>
- * <li> provides ZRTP specific methods that applications may use
- * to control and setup GNU ZRTP
- * </li>
- * <li> can register and use an application specific callback
- * class (refer to ZrtpUserCallback)
- * </li>
- * </ul>
- *
- * After instantiating a GNU ZRTP session (see below for a short
- * example) applications may use the ZRTP specific methods of
- * ZrtpQueue to control and setup GNU ZRTP, for example enable or
- * disable ZRTP processing or getting ZRTP status information.
- *
- * GNU ZRTP provides a ZrtpUserCallback class that an application
- * may extend and register with ZrtpQueue. GNU ZRTP and ZrtpQueue
- * use the ZrtpUserCallback methods to report ZRTP events to the
- * application. The application may display this information to
- * the user or act otherwise.
- *
- * The following figure depicts the relationships between
- * ZrtpQueue, ccRTP RTP/SRTP implementation, the GNU ZRTP core,
- * and an application that provides an ZrtpUserCallback class.
- *
-@verbatim
-
- +----------+
- | ccRTP |
- | RTP/SRTP |
- | |
- +----------+
- ^
- | extends
- |
-+----------------+ +-----+------+
-| Application | | | +-----------------+
-| instantiates | uses | ZrtpQueue | uses | |
-| a ZRTP Session +------+ implements +------+ GNU ZRTP |
-| and provides | |ZrtpCallback| | core |
-|ZrtpUserCallback| | | | implementation |
-+----------------+ +------------+ | (ZRtp et al) |
- | |
- +-----------------+
-@endverbatim
- *
- * Because ZrtpQueue extends the ccRTP RTP/SRTP implementation
- * (AVPQueue) all public methods defined by ccRTP are also
- * available for a ZRTP session. ZrtpQueue overwrites some of the
- * public methods of ccRTP (AVPQueue) to implement ZRTP specific
- * code.
- *
- * GNU ZRTP provides a <em>SymmetricZRTPSession</em> type to
- * simplify its use. An application uses this type in the same way
- * as it would use the normal ccRTP <em>SymmetricRTPSession</em>
- * type. The following short code snippets show how an application
- * could instantiate ccRTP and GNU ZRTP sessions. The first
- * snippet shows how to instantiate a ccRTP session:
- *
- * @code
- * ...
- * #include <ccrtp/rtp.h>
- * ...
- * SymmetricRTPSession tx(pattern.getSsrc(),
- * InetHostAddress("localhost"));
- * ...
- *
- * @endcode
- *
- * The same code as above but using a GNU ZRTP session this time:
- * @code
- * ...
- * #include <libzrtpcpp/zrtpccrtp.h>
- * ...
- * SymmetricZRTPSession tx(pattern.getSsrc(),
- * InetHostAddress("localhost"));
- * ...
- *
- * @endcode
- *
- * The only differences are the different include statements and
- * the different session types.
- *
- * The <em>demo</em> folder contains a small example that shows
- * how to use GNU ZRTP.
- *
- * Please refer to the GNU ccRTP documentation for a description
- * of ccRTP methods and functions. This ZrtpQueue documentation
- * shows the ZRTP specific extensions and describes overloaded
- * methods and a possible different behaviour.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class __EXPORT ZrtpQueue : public AVPQueue, ZrtpCallback {
-
-public:
-
- /**
- * Initialize the ZrtpQueue.
- *
- * Before an application can use ZRTP it has to initialize the
- * ZRTP implementation. This method initializes the timeout
- * thread and opens a file that contains ZRTP specific
- * information such as the applications ZID (ZRTP id) and its
- * retained shared secrets.
- *
- * If one application requires several ZRTP sessions all
- * sessions use the same timeout thread and use the same ZID
- * file. Therefore an application does not need to do any
- * synchronisation regading ZID files or timeouts. This is
- * managed by the ZRTP implementation.
- *
- * The current implementation of ZrtpQueue does not support
- * different ZID files for one application instance. This
- * restriction may be removed in later versions.
- *
- * The application may specify its own ZID file name. If no
- * ZID file name is specified it defaults to
- * <code>$HOME/.GNUccRTP.zid</code> if the <code>HOME</code>
- * environment variable is set. If it is not set the current
- * directory is used.
- *
- * If the method could set up the timeout thread and open the ZID
- * file then it enables ZRTP processing and returns.
- *
- * @param zidFilename
- * The name of the ZID file, can be a relative or absolut
- * filename.
- *
- * @param autoEnable
- * if set to true the method automatically sets enableZrtp to
- * true. This enables the ZRTP auto-sense mode. Default is true.
- *
- * @param config
- * this parameter points to ZRTP configuration data. If it is
- * NULL then ZrtpQueue uses a default setting. Default is NULL.
- *
- * @return
- * 1 on success, ZRTP processing enabled, -1 on failure,
- * ZRTP processing disabled.
- *
- */
- int32_t initialize(const char *zidFilename, bool autoEnable = true,
- ZrtpConfigure* config = NULL);
-
- /*
- * Applications use the following methods to control ZRTP, for example
- * to enable ZRTP, set flags etc.
- */
-
- /**
- * Enable or disable ZRTP processing.
- *
- * Call this method to enable or disable ZRTP processing after
- * calling <code>initialize()</code>. This can be done before
- * using a RTP session or at any time during a RTP session.
- *
- * Existing SRTP sessions or currently active ZRTP processing will
- * not be stopped or disconnected.
- *
- * If the application enables ZRTP then:
- * <ul>
- * <li>ZrtpQueue starts to send ZRTP Hello packets after at least
- * one RTP packet was sent and received on the associated RTP
- * session. Thus if an application enables ZRTP and ZrtpQueue
- * detects traffic on the RTP session then ZrtpQueue automatically
- * starts the ZRTP protocol. This automatic start is convenient
- * for applications that negotiate RTP parameters and set up RTP
- * sessions but the actual RTP traffic starts some time later.
- * </li>
- * <li>ZrtpQueue analyses incoming packets to detect ZRTP
- * messages. If ZRTP was started, either via automatic start (see
- * above) or explicitly via startZrtp(), then ZrtpQueue
- * forwards ZRTP packets to the GNU ZRTP core.
- * </ul>
- *
- * @param onOff
- * @c true to enable ZRTP, @c false to disable ZRTP
- */
- void setEnableZrtp(bool onOff);
-
- /**
- * Return the state of ZRTP enable state.
- *
- * @return @c true if ZRTP processing is enabled, @c false
- * otherwise.
- */
- bool isEnableZrtp();
-
- /**
- * Set SAS as verified.
- *
- * The application may call this method if the user confirmed
- * (verfied) the Short Authentication String (SAS) with the peer.
- *
- * ZRTP calls ZrtpUserCallback#showSAS after it computed the SAS
- * and the application registered a user callback class. The
- * application should display the SAS and provide a mechanism at
- * the user interface that enables the user to confirm the SAS.
- *
- * ZRTP remembers the SAS confirmation status together with the
- * retained secrets data. If both parties confirmed the SAS then
- * ZRTP informs the application about this status on the next ZRTP
- * session.
- *
- * For more detailed information regarding SAS please refer to the
- * ZRTP specification, chapter 8.
- */
- void SASVerified();
-
- /**
- * Reset the SAS verfied flag for the current user's retained secrets.
- *
- */
- void resetSASVerified();
-
- /**
- * To confirm a go clear request.
- *
- * Call this method if the user confirmed a go clear (secure mode off).
- */
- void goClearOk();
-
- /**
- * Request to switch off secure mode.
- *
- * Call this method is the user itself wants to switch off secure
- * mode (go clear). After sending the "go clear" request to the peer
- * ZRTP immediatly switch off SRTP processing. Every RTP data is sent
- * in clear after the go clear request.
- */
- void requestGoClear();
-
- /**
- * Set the auxilliary secret.
- *
- * Use this method to set the srtps secret data. Refer to ZRTP
- * specification, chapter 5.3 ff
- *
- * @param data
- * Points to the auxilliary secret data.
- * @param length
- * Length of the auxilliary secrect in bytes
- */
- void setAuxSecret(uint8_t* data, int32_t length);
-
- /**
- * Set the application's callback class.
- *
- * The destructor of ZrtpQueue also destorys the user callback
- * class if it was set. The application must not delete the
- * callback object or use/reference the callback object after
- * ZrtpQueue was destroyed.
- *
- * @param ucb
- * Implementation of the application's ZrtpUserCallback class
- */
- void setUserCallback(ZrtpUserCallback* ucb);
-
- /**
- * Set the client ID for ZRTP Hello message.
- *
- * The GNU ccRTP client may set its id to identify itself in the
- * ZRTP Hello message. The maximum length is 16 characters. A
- * shorter id string is possible, it will be filled with blanks. A
- * longer id string will be truncated to 16 characters. The
- * standard client id is <code>'GNU ccRTP ZRTP '</code> (without
- * the quotes).
- *
- * Setting the client's id must be done before calling
- * ZrtpQueue#initialize() or ZrtpQueue#startZrtp() .
- *
- * @param id
- * The client's id string
- */
- 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 hex-digits. Refer
- * to ZRTP specification, chapter 9.1.
- *
- * @return
- * 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();
-
- /**
- * Get the peer's ZRTP Hello Hash data.
- *
- * Use this method to get the peer's ZRTP Hello Hash data. The method
- * returns the data as a string containing the ZRTP protocol version and
- * hex-digits.
- *
- * The peer's hello hash is available only after ZRTP received a hello. If
- * no data is available the function returns an empty string.
- *
- * Refer to ZRTP specification, chapter 8.
- *
- * @return
- * a std:string containing the Hello version and the hello hash as hex digits.
- */
- std::string getPeerHelloHash();
-
- /**
- * Get Multi-stream parameters.
- *
- * Use this method to get the Multi-stream that were computed during
- * the ZRTP handshake. An application may use these parameters to
- * enable multi-stream processing for an associated SRTP session.
- *
- * Refer to chapter 5.4.2 in the ZRTP specification for further details
- * and restriction how and when to use multi-stream mode.
- *
- * @return
- * a string that contains the multi-stream parameters. The application
- * must not modify the contents of this string, it is opaque data. The
- * application may hand over this string to a new ZrtpQueue instance
- * to enable multi-stream processing for this ZrtpQueue. If ZRTP was
- * not started or ZRTP is not yet in secure state the method returns an
- * empty string.
- *
- * @see setMultiStrParams()
- */
- std::string getMultiStrParams();
-
- /**
- * Set Multi-stream parameters.
- *
- * Use this method to set the parameters required to enable Multi-stream
- * processing of ZRTP. The multi-stream parameters must be set before the
- * application starts the ZRTP protocol engine.
- *
- * Refer to chapter 5.4.2 in the ZRTP specification for further details
- * of multi-stream mode.
- *
- * @param parameters
- * A string that contains the multi-stream parameters that this
- * new ZrtpQueue instanace shall use.
- *
- * @see getMultiStrParams()
- */
- void setMultiStrParams(std::string parameters);
-
- /**
- * Check if this ZRTP use Multi-stream.
- *
- * Use this method to check if this ZRTP instance uses multi-stream. Even
- * if the application provided multi-stram parameters it may happen that
- * full DH mode was used. Refer to chapters 5.2 and 5.4.2 in the ZRTP #
- * when this may happen.
- *
- * @return
- * True if multi-stream is used, false otherwise.
- */
- bool isMultiStream();
-
- /**
- * Check if the other ZRTP client supports Multi-stream.
- *
- * Use this method to check if the other ZRTP client supports
- * Multi-stream mode.
- *
- * @return
- * True if multi-stream is available, false otherwise.
- */
- bool isMultiStreamAvailable();
-
- /**
- * Accept a PBX enrollment request.
- *
- * If a PBX service asks to enroll the MiTM key and the user accepts this
- * requtes, for example by pressing an OK button, the client application
- * shall call this method and set the parameter <code>accepted</code> to
- * true. If the user does not accept the request set the parameter to
- * false.
- *
- * @param accepted
- * True if the enrollment request is accepted, false otherwise.
- */
- void acceptEnrollment(bool accepted);
-
- /**
- * Get the commited SAS rendering algorithm for this ZRTP session.
- *
- * @return the commited SAS rendering algorithm
- */
- std::string getSasType();
-
- /**
- * Get the computed SAS hash for this ZRTP session.
- *
- * A PBX ZRTP back-to-Back function uses this function to get the SAS
- * hash of an enrolled client to construct the SAS relay packet for
- * the other client.
- *
- * @return a refernce to the byte array that contains the full
- * SAS hash.
- */
- uint8_t* getSasHash();
-
- /**
- * Send the SAS relay packet.
- *
- * The method creates and sends a SAS relay packet according to the ZRTP
- * specifications. Usually only a MitM capable user agent (PBX) uses this
- * function.
- *
- * @param sh the full SAS hash value
- * @param render the SAS rendering algorithm
- */
- bool sendSASRelayPacket(uint8_t* sh, std::string render);
-
- /**
- * Check the state of the MitM mode flag.
- *
- * If true then this ZRTP session acts as MitM, usually enabled by a PBX
- * client (user agent)
- *
- * @return state of mitmMode
- */
- bool isMitmMode();
-
- /**
- * Set the state of the MitM mode flag.
- *
- * If MitM mode is set to true this ZRTP session acts as MitM, usually
- * enabled by a PBX client (user agent).
- *
- * @param mitmMode defines the new state of the mitmMode flag
- */
- void setMitmMode(bool mitmMode);
-
- /**
- * Enable or disable paranoid mode.
- *
- * The Paranoid mode controls the behaviour and handling of the SAS verify flag. If
- * Panaoid mode is set to flase then ZRtp applies the normal handling. If Paranoid
- * mode is set to true then the handling is:
- *
- * <ul>
- * <li> always set the SAS verify flag to <code>false</code> at srtpSecretsOn() callback. The
- * user interface (UI) must show <b>SAS not verified</b>. See implementation note below.</li>
- * <li> don't set the SAS verify flag in the <code>Confirm</code> packets, thus forcing the other
- * peer to report <b>SAS not verified</b>.</li>
- * <li> ignore the <code>SASVerified()</code> function, thus do not set the SAS verified flag
- * in the ZRTP cache. </li>
- * <li> Disable the <em>Trusted PBX MitM</em> feature. Just send the <code>SASRelay</code> packet
- * but do not process the relayed data. This protects the user from a malicious
- * "trusted PBX".</li>
- * </ul>
- * ZRtp performs alls other steps during the ZRTP negotiations as usual, in particular it
- * computes, compares, uses, and stores the retained secrets. This avoids unnecessary warning
- * messages. The user may enable or disable the Paranoid mode on a call-by-call basis without
- * breaking the key continuity data.
- *
- * <b>Implementation note:</b><br/>
- * An application shall <b>always display the SAS if the SAS verify flag is <code>false</code></b>.
- * The application shall remind the user to compare the SAS code, for example using larger fonts,
- * different colours and other display features.
- */
- void setParanoidMode(bool yesNo);
-
- /**
- * Check status of paranoid mode.
- *
- * @return
- * Returns true if paranoid mode is enabled.
- */
- bool isParanoidMode();
-
- /**
- * Check the state of the enrollment mode.
- *
- * If true then we will set the enrollment flag (E) in the confirm
- * packets and performs the enrollment actions. A MitM (PBX) enrollment service sets this flagstarted this ZRTP
- * session. Can be set to true only if mitmMode is also true.
- * @return status of the enrollmentMode flag.
- */
- bool isEnrollmentMode();
-
- /**
- * Check the state of the enrollment mode.
- *
- * If true then we will set the enrollment flag (E) in the confirm
- * packets and perform the enrollment actions. A MitM (PBX) enrollment
- * service must sets this mode to true.
- *
- * Can be set to true only if mitmMode is also true.
- *
- * @param enrollmentMode defines the new state of the enrollmentMode flag
- */
- void setEnrollmentMode(bool enrollmentMode);
-
- /**
- * Check if a peer's cache entry has a vaild MitM key.
- *
- * If true then the other peer ha a valid MtiM key, i.e. the peer has performed
- * the enrollment procedure. A PBX ZRTP Back-2-Back application can use this function
- * to check which of the peers is enrolled.
- *
- * @return True if the other peer has a valid Mitm key (is enrolled).
- */
- bool isPeerEnrolled();
-
- /**
- * Set the state of the SAS signature mode flag.
- *
- * If SAS signature mode is set to true this ZRTP session support SAS signature
- * callbacks and signature transfer between clients.
- *
- * @param sasSignMode defines the new state of the sasSignMode flag
- */
- void setSignSas(bool sasSignMode);
-
- /**
- * Set signature data
- *
- * This functions stores signature data and transmitts it during ZRTP
- * processing to the other party as part of the Confirm packets. Refer to
- * chapters 6.7 and 8.2 in the ZRTP specification.
- *
- * @param data
- * The signature data including the signature type block. The method
- * copies this data into the Confirm packet at signature type block.
- * @param length
- * The length of the signature data in bytes. This length must be
- * multiple of 4.
- * @return
- * True if the method stored the data, false otherwise.
- */
- bool setSignatureData(uint8* data, int32 length);
-
- /**
- * Get signature data
- *
- * This functions returns signature data that was receivied during ZRTP
- * processing. Refer to chapters 6.7 and 8.2.
- *
- * @return
- * Pointer to signature data. This is a pointer to volatile data that is
- * only valid during the checkSASSignature() callback. The application
- * shall copy the data if necessary.
- */
- const uint8* getSignatureData();
-
- /**
- * Get length of signature data
- *
- * This functions returns the length of signature data that was receivied
- * during ZRTP processing. Refer to chapters 6.7 and 8.2.
- *
- * @return
- * Length in bytes of the received signature data. The method returns
- * zero if no signature data avilable.
- */
- int32 getSignatureLength();
-
- /**
- * Put data into the RTP output queue.
- *
- * This is used to create a data packet in the send queue.
- * Sometimes a "NULL" or empty packet will be used instead, and
- * these are known as "silent" packets. "Silent" packets are
- * used simply to "push" the scheduler along more accurately
- * by giving the appearence that a next packet is waiting to
- * be sent and to provide a valid timestamp for that packet.
- *
- * This method overrides the same method in OutgoingDataQueue class.
- * During ZRTP processing it may be necessary to control the
- * flow of outgoing RTP payload packets (GoClear processing).
- *
- * @param stamp Timestamp for expected send time of packet.
- * @param data Value or NULL if special "silent" packet.
- * @param len May be 0 to indicate a default by payload type.
- **/
- void
- putData(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
-
- /**
- * Immediatly send a data packet.
- *
- * This is used to create a data packet and send it immediately.
- * Sometimes a "NULL" or empty packet will be used instead, and
- * these are known as "silent" packets. "Silent" packets are
- * used simply to "push" the scheduler along more accurately
- * by giving the appearence that a next packet is waiting to
- * be sent and to provide a valid timestamp for that packet.
- *
- * This method overrides the same method in OutgoingDataQueue
- * class. During ZRTP processing it may be necessary to
- * control the flow of outgoing RTP payload packets (GoClear
- * processing).
- *
- * @param stamp Timestamp immediate send time of packet.
- * @param data Value or NULL if special "silent" packet.
- * @param len May be 0 to indicate a default by payload type.
- **/
- void
- sendImmediate(uint32 stamp, const unsigned char* data = NULL, size_t len = 0);
-
- /**
- * Starts the ZRTP protocol engine.
- *
- * Applications may call this method to immediatly start the ZRTP protocol
- * engine any time after initializing ZRTP and setting optinal parameters,
- * for example client id or multi-stream parameters.
- *
- * If the application does not call this method but sucessfully initialized
- * the ZRTP engine using <code>initialize()</code> then ZRTP also starts
- * after the application sent and received RTP packets. An application can
- * disable this automatic, delayed start of the ZRTP engine using
- * <code>setEnableZrtp(false)</code> before sending or receiving RTP
- * packets.
- *
- */
- void startZrtp();
-
- /**
- * Stops the ZRTP protocol engine.
- *
- * Applications call this method to stop the ZRTP protocol
- * engine.
- *
- */
- void stopZrtp();
-
- /**
- * Get other party's ZID (ZRTP Identifier) data
- *
- * This functions returns the other party's ZID that was receivied
- * during ZRTP processing.
- *
- * The ZID data can be retrieved after ZRTP receive the first Hello
- * packet from the other party. The application may call this method
- * for example during SAS processing in showSAS(...) user callback
- * method.
- *
- * @param data
- * Pointer to a data buffer. This buffer must have a size of
- * at least 12 bytes (96 bit) (ZRTP Identifier, see chap. 4.9)
- * @return
- * Number of bytes copied into the data buffer - must be equivalent
- * to 96 bit, usually 12 bytes.
- */
- int32 getPeerZid(uint8* data);
-
-protected:
- friend class TimeoutProvider<std::string, ost::ZrtpQueue*>;
-
- /**
- * A hook that gets called if the decoding of an incoming SRTP
- * was erroneous
- *
- * @param pkt
- * The SRTP packet with error.
- * @param errorCode
- * The error code: -1 - SRTP authentication failure, -2 - replay
- * check failed
- * @return
- * True: put the packet in incoming queue for further processing
- * by the applications; false: dismiss packet. The default
- * implementation returns false.
- */
- virtual bool
- onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode);
-
- /**
- * Handle timeout event forwarded by the TimeoutProvider.
- *
- * Just call the ZRTP engine for further processing.
- */
- void handleTimeout(const std::string &c);
-
- /**
- * This function is used by the service thread to process
- * the next incoming packet and place it in the receive list.
- *
- * This class overloads the function of IncomingDataQueue
- * implementation.
- *
- * @return number of payload bytes received, <0 if error.
- */
- virtual size_t takeInDataPacket();
-
- /*
- * The following methods implement the GNU ZRTP callback interface.
- * For detailed documentation refer to file ZrtpCallback.h
- */
- int32_t sendDataZRTP(const unsigned char* data, int32_t length);
-
- int32_t activateTimer(int32_t time);
-
- int32_t cancelTimer();
-
- void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
-
- bool srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part);
-
- void srtpSecretsOff(EnableSecurity part);
-
- void srtpSecretsOn(std::string c, std::string s, bool verified);
-
- void handleGoClear();
-
- void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
-
- void zrtpNotSuppOther();
-
- void synchEnter();
-
- void synchLeave();
-
- void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info);
-
- void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info);
-
- void signSAS(uint8_t* sasHash);
-
- bool checkSASSignature(uint8_t* sasHash);
-
- /*
- * End of ZrtpCallback functions.
- */
-
- ZrtpQueue(uint32 size = RTPDataQueue::defaultMembersHashSize,
- RTPApplication& app = defaultApplication());
-
- /**
- * Local SSRC is given instead of computed by the queue.
- */
- ZrtpQueue(uint32 ssrc, uint32 size =
- RTPDataQueue::defaultMembersHashSize,
- RTPApplication& app = defaultApplication());
-
- virtual ~ZrtpQueue();
-
-private:
- void init();
- size_t rtpDataPacket(unsigned char* packet, int32 rtn,
- InetHostAddress network_address,
- tpport_t transport_port);
-
- ZRtp *zrtpEngine;
- ZrtpUserCallback* zrtpUserCallback;
-
- std::string clientIdString;
-
- bool enableZrtp;
-
- int32 secureParts;
-
- int16 senderZrtpSeqNo;
- ost::Mutex synchLock; // Mutex for ZRTP (used by ZrtpStateClass)
- uint32 peerSSRC;
- bool started;
- bool mitmMode;
- bool signSas;
- bool enableParanoidMode;
-};
-
-class IncomingZRTPPkt : public IncomingRTPPkt {
-
-public:
- /**
- * Build a ZRTP packet object from a data buffer.
- *
- * @param block pointer to the buffer the whole packet is stored in.
- * @param len length of the whole packet, expressed in octets.
- *
- **/
-
- IncomingZRTPPkt(const unsigned char* block, size_t len);
-
- ~IncomingZRTPPkt()
- { }
-
- uint32
- getZrtpMagic() const;
-
- uint32
- getSSRC() const;
-};
-
-class OutgoingZRTPPkt : public OutgoingRTPPkt {
-
-public:
- /**
- * Construct a new ZRTP packet to be sent.
- *
- * A new copy in memory (holding all this components
- * along with the fixed header) is created.
- *
- * @param hdrext whole header extension.
- * @param hdrextlen size of whole header extension, in octets.
- **/
- OutgoingZRTPPkt(const unsigned char* const hdrext, uint32 hdrextlen);
- ~OutgoingZRTPPkt()
- { }
-};
-
-END_NAMESPACE
-
-#endif
-
-/** EMACS **
- * Local variables:
- * mode: c++
- * c-default-style: ellemtel
- * c-basic-offset: 4
- * End:
- */
-
diff --git a/jni/libzrtp/sources/clients/ccrtp/zrtpccrtp.h b/jni/libzrtp/sources/clients/ccrtp/zrtpccrtp.h
deleted file mode 100644
index 3eae183..0000000
--- a/jni/libzrtp/sources/clients/ccrtp/zrtpccrtp.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- 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/>.
-*/
-
-#ifndef _ZRTPCCRTP_H_
-#define _ZRTPCCRTP_H_
-
-#include <ccrtp/rtp.h>
-#include <ZrtpQueue.h>
-
-NAMESPACE_COMMONCPP
-
-// Define a dummy variable only to overcome a doxygen problem.
-static int dummy __attribute__ ((unused)) = 0;
-
-
-/**
- * @typedef SymmetricZRTPSession
- *
- * Uses one pair of sockets, (1) for RTP data and (2) for RTCP
- * transmission/reception.
- *
- * This session uses the ZrtpQueue instead of the AVPQueue. The ZrtpQueue
- * inherits from AVPQueue and adds support for ZRTP thus enabling
- * ad-hoc key negotiation to setup SRTP sessions.
- *
- * @short Symmetric UDP/IPv4 RTP session scheduled by one thread of execution.
- **/
-typedef SingleThreadRTPSession<SymmetricRTPChannel,
- SymmetricRTPChannel,
- ZrtpQueue> SymmetricZRTPSession;
-
-
-#ifdef CCXX_IPV6
-/**
- * @typedef SymmetricZRTPSession
- *
- * Uses one pair of sockets, (1) for RTP data and (2) for RTCP
- * transmission/reception.
- *
- * This session uses the ZrtpQueue instead of the AVPQueue. The ZrtpQueue
- * inherits from AVPQueue and adds support for ZRTP thus enabling
- * ad-hoc key negotiation to setup SRTP sessions.
- *
- * @short Symmetric UDP/IPv6 RTP session scheduled by one thread of execution.
- **/
-typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
- SymmetricRTPChannelIPV6,
- ZrtpQueue> SymmetricZRTPSessionIPV6;
-#endif // CCXX_IPV6
-
-END_NAMESPACE
-
-#endif // _ZRTPCCRTP_H_
-
-
-/** EMACS **
- * Local variables:
- * mode: c++
- * c-default-style: ellemtel
- * c-basic-offset: 4
- * End:
- */
diff --git a/jni/libzrtp/sources/cmake/Modules/FindGcryptConfig.cmake b/jni/libzrtp/sources/cmake/Modules/FindGcryptConfig.cmake
index caeb7c3..1770241 100755
--- a/jni/libzrtp/sources/cmake/Modules/FindGcryptConfig.cmake
+++ b/jni/libzrtp/sources/cmake/Modules/FindGcryptConfig.cmake
@@ -226,12 +226,12 @@
###
macro(gcr_check _prefix _module0)
# check cached value
- if (NOT DEFINED __gcr_config_checked_${_prefix} OR __gcr_config_checked_${_prefix} LESS "${GCR_CONFIG_VERSION}" OR NOT ${_prefix}_FOUND)
+ if (NOT DEFINED __gcr_config_checked_${_prefix} OR __gcr_config_checked_${_prefix} LESS ${GCR_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
_gcrconfig_parse_options (_gcr_modules _gcr_is_required "${_module0}" ${ARGN})
_gcr_check_modules_internal("${_gcr_is_required}" 0 "${_prefix}" ${_gcr_modules})
_gcrconfig_set(__gcr_config_checked_${_prefix} ${GCR_CONFIG_VERSION})
- endif(NOT DEFINED __gcr_config_checked_${_prefix} OR __gcr_config_checked_${_prefix} LESS "${GCR_CONFIG_VERSION}" OR NOT ${_prefix}_FOUND)
+ endif(NOT DEFINED __gcr_config_checked_${_prefix} OR __gcr_config_checked_${_prefix} LESS ${GCR_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
endmacro(gcr_check)
###
diff --git a/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake b/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
index 0eef52f..506b224 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,6 +37,9 @@
"\\\\.la$"
"\\\\.sh$"
"Makefile\\\\.in$"
+ "\\\\.directory$"
+ "\\\\._.DS_Store$"
+ "\\\\._buildmac$"
)
SET(CPACK_PACKAGE_VENDOR "Werner Dittmann")
diff --git a/jni/libzrtp/sources/common/Thread.h b/jni/libzrtp/sources/common/Thread.h
index 3aca167..ca77255 100644
--- a/jni/libzrtp/sources/common/Thread.h
+++ b/jni/libzrtp/sources/common/Thread.h
@@ -62,7 +62,7 @@
#if defined(AS400) || defined(OS400)
typedef pthread_id_np_t ThreadId_t;
-#elif defined(VMS)
+#elif defined(VMS) || defined(__NetBSD__)
typedef pthread_t ThreadId_t;
#else
#ifdef USE_BEGIN_THREAD
@@ -274,7 +274,7 @@
{
#if defined(AS400)||defined(OS400)
return(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?TRUE:FALSE);
-#elif defined(VMS)
+#elif defined(VMS) || defined(__NetBSD__)
return (( pthread_equal(*p1,*p2) )?TRUE:FALSE );
#else
return ((*p1 == *p2)?TRUE:FALSE);
diff --git a/jni/libzrtp/sources/common/osSpecifics.c b/jni/libzrtp/sources/common/osSpecifics.c
index 9c9a1ee..3345363 100644
--- a/jni/libzrtp/sources/common/osSpecifics.c
+++ b/jni/libzrtp/sources/common/osSpecifics.c
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -27,7 +27,7 @@
#endif
#if defined(_WIN32) || defined(_WIN64)
-# include <winsock2.h>
+# include <WinSock2.h>
# include <time.h>
uint64_t zrtpGetTickCount()
diff --git a/jni/libzrtp/sources/common/osSpecifics.h b/jni/libzrtp/sources/common/osSpecifics.h
index 494dc0a..5030688 100644
--- a/jni/libzrtp/sources/common/osSpecifics.h
+++ b/jni/libzrtp/sources/common/osSpecifics.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -34,6 +34,23 @@
* @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"
{
diff --git a/jni/libzrtp/sources/libzrtpcpp-config.h.cmake b/jni/libzrtp/sources/config.h.cmake
similarity index 100%
rename from jni/libzrtp/sources/libzrtpcpp-config.h.cmake
rename to jni/libzrtp/sources/config.h.cmake
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
index 7078b72..c19fa82 100644
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
+++ b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2006-2012 Werner Dittmann
+ * 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 General Public License as published by
+ * 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.
*
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
index 3487a27..d3eedf7 100644
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
+++ b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.cpp b/jni/libzrtp/sources/cryptcommon/macSkein.cpp
index a6e1633..9da946f 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.cpp
+++ b/jni/libzrtp/sources/cryptcommon/macSkein.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2010-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.h b/jni/libzrtp/sources/cryptcommon/macSkein.h
index 3fdb8f0..ce5d380 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.h
+++ b/jni/libzrtp/sources/cryptcommon/macSkein.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2010-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/cryptcommon/twofish.c b/jni/libzrtp/sources/cryptcommon/twofish.c
index 45b2bb0..03d2770 100644
--- a/jni/libzrtp/sources/cryptcommon/twofish.c
+++ b/jni/libzrtp/sources/cryptcommon/twofish.c
@@ -475,8 +475,17 @@
(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
diff --git a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c b/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
index 80925f4..241b956 100755
--- a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
+++ b/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
@@ -20,8 +20,20 @@
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);
+
+/*
+ * 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;
@@ -31,8 +43,8 @@
if (len) {
Twofish_encrypt(keyCtx, ivec, ivec);
while (len--) {
- out[n] = ivec[n] ^= in[n];
- ++n;
+ out[n] = ivec[n] ^= in[n];
+ ++n;
}
}
*num = n;
diff --git a/jni/libzrtp/sources/demo/CMakeLists.txt b/jni/libzrtp/sources/demo/CMakeLists.txt
index e75a63a..c253d9f 100755
--- a/jni/libzrtp/sources/demo/CMakeLists.txt
+++ b/jni/libzrtp/sources/demo/CMakeLists.txt
@@ -1,22 +1,27 @@
#to make sure includes are first taken - it contains config.h
include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/../zrtp
- ${CMAKE_CURRENT_SOURCE_DIR}/../clients/ccrtp)
+include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/zrtp
+ ${CMAKE_SOURCE_DIR}/clients/ccrtp)
-########### next target ###############
+if (CCRTP)
+ ########### next target ###############
-add_executable(zrtptest zrtptest.cpp)
-target_link_libraries(zrtptest zrtpcpp ccrtp commoncpp)
-add_dependencies(zrtptest zrtpcpp)
+ add_executable(zrtptest zrtptest.cpp)
+ target_link_libraries(zrtptest ${zrtplibName})
+ add_dependencies(zrtptest ${zrtplibName})
-########### next target ###############
+ ########### next target ###############
-add_executable(zrtptestMulti zrtptestMulti.cpp)
-target_link_libraries(zrtptestMulti zrtpcpp ccrtp commoncpp)
-add_dependencies(zrtptestMulti zrtpcpp)
-
+ 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
new file mode 100644
index 0000000..a329e8d
--- /dev/null
+++ b/jni/libzrtp/sources/demo/sdestest.cpp
@@ -0,0 +1,231 @@
+#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 fc3490d..0595543 100644
--- a/jni/libzrtp/sources/demo/zrtptest.cpp
+++ b/jni/libzrtp/sources/demo/zrtptest.cpp
@@ -16,9 +16,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#include <commoncpp/string.h>
-
-
#include <cstdlib>
#include <map>
#include <zrtpccrtp.h>
@@ -31,40 +28,36 @@
class PacketsPattern
{
public:
- inline const InetHostAddress&
- getDestinationAddress() const
- { return destinationAddress; }
+ inline const InetHostAddress& getReceiverAddress() const { return *receiverAddress; }
+ inline const InetHostAddress& getSenderAddress() const { return *senderAddress; }
- inline const tpport_t
- getDestinationPort() const
- { return destinationPort; }
+ inline void setReceiverAddress(InetHostAddress *addr) const { delete receiverAddress; receiverAddress = addr; }
+ inline void setSenderAddress(InetHostAddress *addr) const { delete senderAddress; senderAddress = addr; }
- uint32
- getPacketsNumber() const
- { return packetsNumber; }
+ inline const tpport_t getReceiverPort() const { return receiverPort; }
+ inline const tpport_t getSenderPort() const { return senderPort; }
- uint32
- getSsrc() const
- { return 0xdeadbeef; }
+ uint32 getPacketsNumber() const { return packetsNumber; }
- const unsigned char*
- getPacketData(uint32 i)
- { return data[i%2]; }
+ uint32 getSsrc() const { return 0xdeadbeef; }
- const size_t
- getPacketSize(uint32 i)
- { return strlen((char*)data[i%2]) + 1 ; }
+ const unsigned char*getPacketData(uint32 i) { return data[i%2]; }
+
+ const size_t getPacketSize(uint32 i) { return strlen((char*)data[i%2]) + 1 ; }
private:
- static const InetHostAddress destinationAddress;
- static const uint16 destinationPort = 5002;
+ static const InetHostAddress *receiverAddress;
+ static const InetHostAddress *senderAddress;
+
+ static const uint16 receiverPort = 5002;
+ static const uint16 senderPort = 5004;
static const uint32 packetsNumber = 10;
static const uint32 packetsSize = 12;
static const unsigned char* data[];
};
-const InetHostAddress PacketsPattern::destinationAddress =
- InetHostAddress("localhost");
+const InetHostAddress *PacketsPattern::receiverAddress = new InetHostAddress("localhost");
+const InetHostAddress *PacketsPattern::senderAddress = new InetHostAddress("localhost");
const unsigned char* PacketsPattern::data[] = {
(unsigned char*)"0123456789\n",
@@ -76,7 +69,7 @@
class ExtZrtpSession : public SymmetricZRTPSession {
// ExtZrtpSession(InetMcastAddress& ima, tpport_t port) :
// RTPSession(ima,port) {}
-//
+//
// ExtZrtpSession(InetHostAddress& ia, tpport_t port) :
// RTPSession(ia,port) {}
@@ -118,6 +111,13 @@
};
+/*
+ * 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 +135,7 @@
int doTest() {
// should be valid?
//RTPSession tx();
- ExtZrtpSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
+ ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
// SymmetricZRTPSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
tx.setSchedulingTimeout(10000);
tx.setExpireTimeout(1000000);
@@ -143,8 +143,9 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
- if (!tx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()) ) {
+
+ // We are sender:
+ if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
return 1;
}
@@ -177,8 +178,7 @@
int
doTest() {
- ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
- pattern.getDestinationPort());
+ ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
// SymmetricZRTPSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
// pattern.getDestinationPort());
@@ -188,8 +188,7 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()+2) ) {
+ if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
return 1;
}
for ( int i = 0; i < 5000 ; i++ ) {
@@ -228,8 +227,8 @@
int doTest() {
// should be valid?
//RTPSession tx();
- ExtZrtpSession tx(pattern.getSsrc(), pattern.getDestinationAddress(),
- pattern.getDestinationPort()+2);
+ // Initialize with local address and Local port is detination port +2 - keep RTP/RTCP port pairs
+ ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
tx.initialize("test_t.zid");
tx.setSchedulingTimeout(10000);
@@ -238,8 +237,7 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
- if (!tx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()) ) {
+ if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
return 1;
}
tx.startZrtp();
@@ -271,8 +269,7 @@
int
doTest() {
- ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
- pattern.getDestinationPort());
+ ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
rx.initialize("test_r.zid");
@@ -282,8 +279,7 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()+2) ) {
+ if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
return 1;
}
rx.startZrtp();
@@ -348,6 +344,8 @@
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!")));
@@ -453,6 +451,8 @@
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.
*
@@ -471,38 +471,52 @@
ZrtpConfigure config;
- void run()
- {
+ void run() {
doTest();
}
- int doTest()
- {
+ int doTest() {
// should be valid?
//RTPSession tx();
- ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getDestinationAddress(),
- pattern.getDestinationPort()+2);
-// config.clear();
+ ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getSenderAddress(), pattern.getSenderPort());
+ config.clear();
// config.setStandardConfig();
- config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
+// 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("S384"));
+ config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
-// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
-// config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
+ 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);
// 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.
- cout << "TX Hello hash: " << tx.getHelloHash() << endl;
- cout << "TX Hello hash length: " << tx.getHelloHash().length() << endl;
-
+ 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;
+ }
tx.setUserCallback(new MyUserCallback(&tx));
+ tx.setAuxSecret(transmAuxSecret, sizeof(transmAuxSecret));
tx.setSchedulingTimeout(10000);
tx.setExpireTimeout(1000000);
@@ -510,8 +524,8 @@
tx.startRunning();
tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
- if (!tx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()) ) {
+
+ if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
return 1;
}
tx.startZrtp();
@@ -535,29 +549,49 @@
}
};
+static unsigned char recvAuxSecret[] = {1,2,3,4,5,6,7,8,9,9};
class
ZrtpRecvPacketTransmissionTestCB: public Thread
{
public:
- void
- run() {
+ ZrtpConfigure config;
+
+ void run() {
doTest();
}
- int
- doTest() {
- ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getDestinationAddress(),
- pattern.getDestinationPort());
+ int doTest() {
+ ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getReceiverAddress(), pattern.getReceiverPort());
+ config.clear();
+// config.setStandardConfig();
+// config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
- rx.initialize("test_r.zid");
+ 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);
// 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.
- cout << "RX Hello hash: " << rx.getHelloHash() << endl;
- cout << "RX Hello hash length: " << rx.getHelloHash().length() << endl;
-
+ 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;
+ }
rx.setUserCallback(new MyUserCallback(&rx));
+ rx.setAuxSecret(recvAuxSecret, sizeof(recvAuxSecret));
rx.setSchedulingTimeout(10000);
rx.setExpireTimeout(1000000);
@@ -565,8 +599,7 @@
rx.startRunning();
rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
// arbitrary number of loops to provide time to start transmitter
- if (!rx.addDestination(pattern.getDestinationAddress(),
- pattern.getDestinationPort()+2) ) {
+ if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
return 1;
}
rx.startZrtp();
@@ -598,7 +631,7 @@
/* check args */
while (1) {
- c = getopt(argc, argv, "rs");
+ c = getopt(argc, argv, "rsR:S:");
if (c == -1) {
break;
}
@@ -609,6 +642,12 @@
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 8fd288b..d7042ed 100644
--- a/jni/libzrtp/sources/demo/zrtptestMulti.cpp
+++ b/jni/libzrtp/sources/demo/zrtptestMulti.cpp
@@ -488,7 +488,8 @@
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);
@@ -499,13 +500,12 @@
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,8 +518,13 @@
// 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.
- cout << prefix << "Hello hash: " << tx->getHelloHash() << endl;
- cout << prefix << "Hello hash length: " << tx->getHelloHash().length() << endl;
+ 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;
+ }
tx->setUserCallback(mcb);
tx->setSchedulingTimeout(10000);
tx->setExpireTimeout(1000000);
@@ -583,12 +588,14 @@
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);
@@ -599,8 +606,13 @@
// 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.
- cout << prefix << "Hello hash: " << rx->getHelloHash() << endl;
- cout << prefix << "Hello hash length: " << rx->getHelloHash().length() << endl;
+ 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;
+ }
rx->setUserCallback(mcb);
rx->setSchedulingTimeout(10000);
rx->setExpireTimeout(1000000);
diff --git a/jni/libzrtp/sources/directive b/jni/libzrtp/sources/directive
index 6670679..016351a 100644
--- a/jni/libzrtp/sources/directive
+++ b/jni/libzrtp/sources/directive
@@ -1,3 +1 @@
-version: 1.1
directory: ccrtp
-filename: libzrtpcpp-2.2.1.tar.gz
diff --git a/jni/libzrtp/sources/libzrtpcpp.pc.cmake b/jni/libzrtp/sources/libzrtpcpp.pc.cmake
index f9f5541..655bd30 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@zrtplib@
+Libs: -L${libdir} -l@zrtplibName@
Cflags: -I${includedir}
diff --git a/jni/libzrtp/sources/srtp/CryptoContext.cpp b/jni/libzrtp/sources/srtp/CryptoContext.cpp
index a6e8768..89eb699 100644
--- a/jni/libzrtp/sources/srtp/CryptoContext.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContext.cpp
@@ -388,22 +388,18 @@
int64_t delta = guessed_index - local_index;
if (delta > 0) {
- /* Packet not yet received*/
- return true;
+ return true; /* Packet not yet received*/
}
else {
- if ( -delta > REPLAY_WINDOW_SIZE ) {
- /* Packet too old */
- return false;
+ if ( -delta >= REPLAY_WINDOW_SIZE ) {
+ return false; /* Packet too old */
}
else {
if ((replay_window >> (-delta)) & 0x1) {
- /* Packet already received ! */
- return false;
+ return false; /* Packet already received ! */
}
else {
- /* Packet not yet received */
- return true;
+ return true; /* Packet not yet received */
}
}
}
diff --git a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
index e331be9..952a823 100644
--- a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
@@ -341,24 +341,21 @@
return true;
}
- int64_t delta = s_l - index;
+ int64_t delta = index - s_l;
if (delta > 0) {
/* Packet not yet received*/
return true;
}
else {
- if( -delta > REPLAY_WINDOW_SIZE ) {
- /* Packet too old */
- return false;
+ if( -delta >= REPLAY_WINDOW_SIZE ) {
+ return false; /* Packet too old */
}
else {
if((replay_window >> (-delta)) & 0x1) {
- /* Packet already received ! */
- return false;
+ return false; /* Packet already received ! */
}
else {
- /* Packet not yet received */
- return true;
+ return true; /* Packet not yet received */
}
}
}
@@ -376,7 +373,8 @@
else {
replay_window |= ( 1 << delta );
}
- s_l = index;
+ if (index > s_l)
+ s_l = index;
}
CryptoContextCtrl* CryptoContextCtrl::newCryptoContextForSSRC(uint32_t ssrc)
diff --git a/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
index cb17b8f..1c743d2 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-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
index 7346522..abe0a81 100644
--- a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2008 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -133,4 +133,5 @@
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
index 2c02a1e..5975fc2 100644
--- a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2008 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
index 0bd91f0..b097cbf 100644
--- a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -29,11 +29,6 @@
memcpy(record.rs2, record.rs1, RS_LENGTH);
record.rs2Ttl = record.rs1Ttl;
- // now propagate flags as well
- if (isRs1Valid()) {
- setRs2Valid();
- }
-
// set new RS1 data
memcpy(record.rs1, data, RS_LENGTH);
@@ -48,6 +43,7 @@
validThru = time(NULL) + expire;
}
record.rs1Ttl = validThru;
+ resetRs2Valid();
setRs1Valid();
}
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
index 68a4b9c..fd25dec 100644
--- a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -29,11 +29,6 @@
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);
@@ -55,6 +50,7 @@
else {
memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);
}
+ resetRs2Valid();
setRs1Valid();
}
diff --git a/jni/libzrtp/sources/zrtp/ZRtp.cpp b/jni/libzrtp/sources/zrtp/ZRtp.cpp
index 9fb8e0a..c7d2a46 100755
--- a/jni/libzrtp/sources/zrtp/ZRtp.cpp
+++ b/jni/libzrtp/sources/zrtp/ZRtp.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -25,6 +25,12 @@
#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>
@@ -52,7 +58,7 @@
}
fprintf(stderr, "\n");
}
- */
+ * */
/*
* This method simplifies detection of libzrtpcpp inside Automake, configure
@@ -73,9 +79,10 @@
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) {
+ enrollmentMode(false), configureAlgos(*config), zidRec(NULL), saveZidRecord(true) {
enableMitmEnrollment = config->isTrustedMitM();
+ signatureData = NULL;
paranoidMode = config->isParanoidMode();
// setup the implicit hash function pointers and length
@@ -86,6 +93,8 @@
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.
@@ -95,21 +104,40 @@
sha256(H1, HASH_IMAGE_SIZE, H2); // H2
sha256(H2, HASH_IMAGE_SIZE, H3); // H3
- zrtpHello.configureHello(&configureAlgos);
- zrtpHello.setH3(H3); // set H3 in Hello, included in helloHash
+ // 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_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_11.setMitmMode();
+ zrtpHello_12.setMitmMode();
+ }
+ if (sasSignSupport) { // the application supports SAS signing
+ zrtpHello_11.setSasSign();
+ zrtpHello_12.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;
- memcpy(ownZid, myZid, ZID_SIZE);
- zrtpHello.setZid(ownZid);
-
- if (mitmm) // this session acts for a trusted MitM (PBX)
- zrtpHello.setMitmMode();
-
- if (sasSignSupport) // the application supports SAS signing
- zrtpHello.setSasSign();
-
- setClientId(id); // set id, compute HMAC and final helloHash
-
stateEngine = new ZrtpStateClass(this);
}
@@ -235,7 +263,7 @@
}
ZrtpPacketHello* ZRtp::prepareHello() {
- return &zrtpHello;
+ return currentHelloPacket;
}
ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
@@ -249,16 +277,17 @@
*/
ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
+ myRole = Initiator;
+
+ if (!hello->isLengthOk()) {
+ *errMsg = CriticalSWError;
+ 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;
- if (memcmp(hello->getVersion(), zrtpVersion, ZRTP_WORD_SIZE-1) != 0) {
- *errMsg = UnsuppZRTPVersion;
- return NULL;
- }
-
// 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????
@@ -291,14 +320,15 @@
sasType = findBestSASType(hello);
if (!multiStream) {
- pubKey = findBestPubkey(hello); // Check for public key algorithm first, sets 'hash' as well
+ 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);
- authLength = findBestAuthLen(hello);
+ if (authLength == NULL) // public key selection may have set the SRTP authLen already
+ authLength = findBestAuthLen(hello);
multiStreamAvailable = checkMultiStream(hello);
}
else {
@@ -440,7 +470,7 @@
}
/*
- * At this point we will take the role of the Responder. We may have been in
+ * At this point we will take the role of the Responder. We 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
@@ -452,8 +482,21 @@
sendInfo(Info, InfoRespCommitReceived);
- // The following code check the hash chain according chapter 10 to detect
- // false ZRTP packets.
+ 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.
// Must use the implicit hash function.
uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
@@ -511,8 +554,8 @@
*errMsg = UnsuppPKExchange;
return NULL;
}
- if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38) {
- if (*(int32_t*)(hash->getName()) != *(int32_t*)s384) {
+ 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;
}
@@ -528,7 +571,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())) {
@@ -540,7 +583,11 @@
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);
@@ -561,22 +608,20 @@
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 a possibly pre-computed SHA context
- // because this was prepared for Initiator. Then create a new one.
+ // We are responder. Release the pre-computed SHA context because it was prepared for Initiator.
+ // Setup and compute for Responder.
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*)zrtpHello.getHeaderBase(), zrtpHello.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*)currentHelloPacket->getHeaderBase(), currentHelloPacket->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);
@@ -595,6 +640,10 @@
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.
@@ -633,8 +682,6 @@
}
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.
@@ -667,6 +714,10 @@
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
@@ -689,7 +740,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, &zrtpHello);
+ computeHvi(dhPart2, currentHelloPacket);
if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
*errMsg = DHErrorWrongHVI;
return NULL;
@@ -706,8 +757,8 @@
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);
@@ -770,6 +821,10 @@
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
@@ -840,7 +895,7 @@
// First the Responder's (my) Hello message, second the Commit
// (always Initator's)
// use negotiated hash
- hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
+ hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
closeHashCtx(msgShaContext, messageHash);
@@ -878,6 +933,10 @@
sendInfo(Info, InfoInitConf1Received);
+ if (!confirm1->isLengthOk()) {
+ *errMsg = CriticalSWError;
+ return NULL;
+ }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -903,7 +962,7 @@
return NULL;
}
signatureLength = confirm1->getSignatureLength();
- if (signSasSeen && signatureLength > 0) {
+ if (signSasSeen && signatureLength > 0 && confirm1->isSignatureLengthOk()) {
signatureData = confirm1->getSignatureData();
callback->checkSASSignature(sasHash);
// TODO: error handling if checkSASSignature returns false.
@@ -956,7 +1015,8 @@
zrtpConfirm2.setPBXEnrollment();
}
}
- getZidCacheInstance()->saveRecord(zidRec);
+ if (saveZidRecord)
+ getZidCacheInstance()->saveRecord(zidRec);
// Encrypt and HMAC with Initiator's key - we are Initiator here
hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
@@ -994,6 +1054,10 @@
// don't update SAS, RS
sendInfo(Info, InfoInitConf1Received);
+ if (!confirm1->isLengthOk()) {
+ *errMsg = CriticalSWError;
+ return NULL;
+ }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -1059,6 +1123,10 @@
sendInfo(Info, InfoRespConf2Received);
+ if (!confirm2->isLengthOk()) {
+ *errMsg = CriticalSWError;
+ return NULL;
+ }
uint8_t confMac[MAX_DIGEST_LENGTH];
uint32_t macLen;
@@ -1088,7 +1156,7 @@
return NULL;
}
signatureLength = confirm2->getSignatureLength();
- if (signSasSeen && signatureLength > 0) {
+ if (signSasSeen && signatureLength > 0 && confirm2->isSignatureLengthOk() ) {
signatureData = confirm2->getSignatureData();
callback->checkSASSignature(sasHash);
// TODO: error handling if checkSASSignature returns false.
@@ -1106,7 +1174,8 @@
// save new RS1, this inherits the verified flag from old RS1
zidRec->setNewRs1((const uint8_t*)newRs1);
- getZidCacheInstance()->saveRecord(zidRec);
+ if (saveZidRecord)
+ getZidCacheInstance()->saveRecord(zidRec);
// Ask for enrollment only if enabled via configuration and the
// confirm packet contains the enrollment flag. The enrolling user
@@ -1141,7 +1210,10 @@
}
ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
- sendInfo(ZrtpError, epkt->getErrorCode() * -1);
+ if (epkt->getLength() < 4)
+ sendInfo(ZrtpError, CriticalSWError * -1);
+ else
+ sendInfo(ZrtpError, epkt->getErrorCode() * -1);
return &zrtpErrorAck;
}
@@ -1151,7 +1223,8 @@
}
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)
@@ -1167,6 +1240,10 @@
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) {
@@ -1287,8 +1364,7 @@
if (num == 0) {
return &zrtpHashes.getByName(mandatoryHash);
}
- // Build list of configured hash algorithm names, append mandatory algos
- // if necessary.
+ // Build list of configured hash algorithm names.
numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
@@ -1302,8 +1378,7 @@
numAlgosOffered++;
}
- // Lookup offered algos in configured algos. Because of appended
- // mandatory algorithms at least one match will happen
+ // Lookup offered algos in configured algos.
for (i = 0; i < numAlgosOffered; i++) {
for (ii = 0; ii < numAlgosConf; ii++) {
if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1354,85 +1429,101 @@
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) {
- int i;
- int ii;
- int numAlgosIntersect;
- AlgorithmEnum* algosIntersect[ZrtpConfigure::maxNoOfAlgos+1];
-
- int numAlgosConf;
- AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
+ AlgorithmEnum* peerIntersect[ZrtpConfigure::maxNoOfAlgos+1];
+ AlgorithmEnum* ownIntersect[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, ec25, dh3k, ec38};
+ const char *orderedAlgos[] = {dh2k, e255, ec25, dh3k, e414, ec38};
int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);
- int num = hello->getNumPubKeys();
- if (num == 0) {
- hash = &zrtpHashes.getByName(mandatoryHash); // set mandatory hash
+ int numAlgosPeer = hello->getNumPubKeys();
+ if (numAlgosPeer == 0) {
+ hash = findBestHash(hello); // find a hash algorithm
return &zrtpPubKeys.getByName(mandatoryPubKey);
}
- // 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) {
+ // 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) {
continue; // skip multi-stream mode
}
- ii++;
- }
- numAlgosConf = ii;
-
- // Build list of intersecting algos: own and offered in Hello, intersect list is ordered according to offered algorithms
- for (numAlgosIntersect = 0, i = 0; i < num; i++) {
- for (ii = 0; ii < numAlgosConf; ii++) {
- algosIntersect[numAlgosIntersect] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
- if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)(algosIntersect[numAlgosIntersect]->getName())) {
- numAlgosIntersect++;
+ 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 (numAlgosIntersect == 0) {
- // If we don't find a common algorithm - use the mandatory algorithms
- hash = &zrtpHashes.getByName(mandatoryHash);
+ // 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 (numAlgosIntersect > 1 && *(int32_t*)(algosConf[0]->getName()) != *(int32_t*)(algosIntersect[0]->getName())) {
+ if (numPeerIntersect > 1 && *(int32_t*)(ownIntersect[0]->getName()) != *(int32_t*)(peerIntersect[0]->getName())) {
int own, peer;
- const int32_t *name = (int32_t*)algosConf[0]->getName();
+ 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*)algosIntersect[0]->getName();
+ name = (int32_t*)peerIntersect[0]->getName();
for (peer = 0; peer < numOrderedAlgos; peer++) {
if (*name == *(int32_t*)orderedAlgos[peer])
break;
}
if (own < peer) {
- useAlgo = algosConf[0];
+ useAlgo = ownIntersect[0];
}
else {
- useAlgo = algosIntersect[0];
+ useAlgo = peerIntersect[0];
}
// find fastest of conf vs intersecting
}
else {
- useAlgo = algosIntersect[0];
+ useAlgo = peerIntersect[0];
}
+ int32_t algoName = *(int32_t*)(useAlgo->getName());
+
// select a corresponding strong hash if necessary.
- if (*(int32_t*)(useAlgo->getName()) == *(int32_t*)ec38) {
- hash = getStrongHashOffered(hello);
- cipher = getStrongCipherOffered(hello);
+ if (algoName == *(int32_t*)ec38 || algoName == *(int32_t*)e414) {
+ hash = getStrongHashOffered(hello, algoName);
+ cipher = getStrongCipherOffered(hello, algoName);
}
else {
- hash = findBestHash(hello);
+ hash = getHashOffered(hello, algoName);;
+ cipher = getCipherOffered(hello, algoName);
}
+ authLength = getAuthLenOffered(hello, algoName);
return useAlgo;
}
@@ -1450,14 +1541,14 @@
if (num == 0) {
return &zrtpSasTypes.getByName(mandatorySasType);
}
- // Buildlist of configured SAS algorithm names
+ // Build list of configured SAS algorithm names
numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);
for (i = 0; i < numAlgosConf; i++) {
algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);
}
// Build list of offered known algos in Hello,
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++;
@@ -1515,27 +1606,109 @@
return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
}
-AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello) {
+// 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++) {
- if (*(int32_t*)(hello->getHashType(i)) == *(int32_t*)s384) {
+ 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;
+ return NULL; // returning NULL -> prepareCommit(...) terminates ZRTP, missing strong hash is an error
}
-AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello) {
+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++) {
- if (*(int32_t*)(hello->getCipherType(i)) == *(int32_t*)aes3 ||
- *(int32_t*)(hello->getCipherType(i)) == *(int32_t*)two3) {
+ 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;
+ 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) {
@@ -1558,6 +1731,10 @@
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;
@@ -1593,6 +1770,7 @@
uint8_t randBuf[RS_LENGTH];
uint32_t macLen;
+ fprintf(stderr, "Compute shared secrets\n");
detailInfo.secretsCached = 0;
if (!zidRec->isRs1Valid()) {
randomZRTP(randBuf, RS_LENGTH);
@@ -1618,15 +1796,6 @@
detailInfo.secretsCached |= Rs2;
}
- /*
- * For the time being we don't support this type 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);
@@ -1638,6 +1807,28 @@
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);
+ }
+ }
}
/*
@@ -1684,12 +1875,17 @@
rsFound = 0x8;
detailInfo.secretsMatched = Rs2;
}
- /* *** Not yet supported
+
if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
- DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
+ DEBUGOUT((fprintf(stdout, "Initiator: Match for aux secret found\n")));
setD[1] = auxSecret;
+ detailInfo.secretsMatched |= Aux;
+ detailInfo.secretsMatchedDH |= Aux;
}
- */
+ 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) {
DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
@@ -1704,6 +1900,7 @@
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
}
else { // No valid RS record in cache
sendInfo(Warning, WarningNoRSMatch);
@@ -1780,7 +1977,7 @@
data[pos] = (unsigned char*)&sLen[i];
length[pos++] = sizeof(uint32_t);
data[pos] = (unsigned char*)setD[i];
- length[pos++] = RS_LENGTH;
+ length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
}
else { // no machting secret, set length 0, skip secret
sLen[i] = 0;
@@ -1842,12 +2039,17 @@
rsFound |= 0x8;
detailInfo.secretsMatched = Rs2;
}
- /* ***** not yet supported
- if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
- DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", ownZidzid[0])));
- setD[1] = ;
+
+ 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;
}
- */
+ // 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])));
@@ -1861,6 +2063,7 @@
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
}
else { // No valid RS record in cache
sendInfo(Warning, WarningNoRSMatch);
@@ -1939,7 +2142,7 @@
data[pos] = (unsigned char*)&sLen[i];
length[pos++] = sizeof(uint32_t);
data[pos] = (unsigned char*)setD[i];
- length[pos++] = RS_LENGTH;
+ length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
}
else { // no machting secret, set length 0, skip secret
sLen[i] = 0;
@@ -2189,6 +2392,34 @@
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;
}
}
@@ -2202,6 +2433,7 @@
return;
zidRec->setSasVerified();
+ saveZidRecord = true;
getZidCacheInstance()->saveRecord(zidRec);
}
@@ -2211,6 +2443,14 @@
getZidCacheInstance()->saveRecord(zidRec);
}
+void ZRtp::setRs2Valid() {
+
+ if (zidRec != NULL) {
+ zidRec->setRs2Valid();
+ if (saveZidRecord)
+ getZidCacheInstance()->saveRecord(zidRec);
+ }
+}
void ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
@@ -2262,33 +2502,32 @@
}
}
-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());
- }
+void ZRtp::setClientId(std::string id, HelloPacketVersion* hpv) {
- int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
+ 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;
- // Hello packet is ready now, compute its HMAC
+ hpv->packet->setClientId(tmp);
+
+ int32_t len = hpv->packet->getLength() * ZRTP_WORD_SIZE;
+
+ // Hello packets are 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*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
- zrtpHello.setHMAC(hmac);
+ hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)hpv->packet->getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
+ hpv->packet->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*)zrtpHello.getHeaderBase(), len, helloHash);
+ hashFunctionImpl((uint8_t*)hpv->packet->getHeaderBase(), len, hpv->helloHash);
}
void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
- int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
+ uint32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
+ length = (length > sizeof(tempMsgBuffer)) ? sizeof(tempMsgBuffer) : length;
memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
lengthOfMsgData = length;
@@ -2304,12 +2543,18 @@
return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
}
-std::string ZRtp::getHelloHash() {
+std::string ZRtp::getHelloHash(int32_t index) {
std::ostringstream stm;
- uint8_t* hp = helloHash;
+ if (index < 0 || index >= MAX_ZRTP_VERSIONS)
+ return std::string();
- stm << zrtpVersion;
+ uint8_t* hp = helloPackets[index].helloHash;
+
+ char version[5] = {'\0'};
+ strncpy(version, (const char*)helloPackets[index].packet->getVersion(), ZRTP_WORD_SIZE);
+
+ stm << version;
stm << " ";
stm.fill('0');
stm << hex;
@@ -2426,7 +2671,8 @@
Event_t ev;
ev.type = ZrtpPacket;
- ev.packet = (uint8_t*)&zrtpConf2Ack;
+ ev.packet = (uint8_t*)zrtpConf2Ack.getHeaderBase();
+ ev.length = sizeof (Conf2AckPacket_t) + 12; // 12 is fixed ZRTP (RTP) header size
if (stateEngine != NULL) {
stateEngine->processEvent(&ev);
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp b/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
index f8e0c65..7f7c3dd 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C calls to ZRTP C++ methods.
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2010-2013 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
+ 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.
@@ -164,10 +164,10 @@
zrtpContext->zrtpEngine->resetSASVerified();
}
-char* zrtp_getHelloHash(ZrtpContext* zrtpContext) {
+char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index) {
std::string ret;
if (zrtpContext && zrtpContext->zrtpEngine)
- ret = zrtpContext->zrtpEngine->getHelloHash();
+ ret = zrtpContext->zrtpEngine->getHelloHash(index);
else
return NULL;
@@ -324,6 +324,13 @@
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/zrtp/ZrtpCallbackWrapper.cpp
index ca2dce6..fed2c04 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C++ callback methods to C callback methods.
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2010-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp b/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
index bb71269..6a22983 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
@@ -1,3 +1,24 @@
+/*
+ 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/ZrtpConfigure.h>
@@ -135,6 +156,8 @@
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);
}
HashEnum::~HashEnum() {}
@@ -156,10 +179,14 @@
*/
PubKeyEnum::PubKeyEnum() : EnumBase(PubKeyAlgorithm) {
insert(dh2k, 0, "DH-2048", NULL, NULL, None);
- insert(ec25, 0, "ECDH-256", NULL, NULL, None);
+ insert(ec25, 0, "NIST ECDH-256", NULL, NULL, None);
insert(dh3k, 0, "DH-3072", NULL, NULL, None);
- insert(ec38, 0, "ECDH-384", NULL, NULL, None);
- insert(mult, 0, "Multi-stream", 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
}
PubKeyEnum::~PubKeyEnum() {}
@@ -198,7 +225,8 @@
/*
* The public methods are mainly a facade to the private methods.
*/
-ZrtpConfigure::ZrtpConfigure() : enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false) {}
+ZrtpConfigure::ZrtpConfigure(): enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false),
+selectionPolicy(Standard){}
ZrtpConfigure::~ZrtpConfigure() {}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
index 85f1484..5a96f52 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
index af4bb09..b582777 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
index f35dc82..67a51ee 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
index f558759..6f13cae 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -66,6 +66,17 @@
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/zrtp/ZrtpPacketDHPart.cpp
index 8c59233..1a89e16 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -59,6 +59,12 @@
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;
@@ -74,18 +80,24 @@
int16_t len = getLength();
DEBUGOUT((fprintf(stdout, "DHPart length: %d\n", len)));
- if (len == 85) {
+ if (len == 85) { // Dh2k
dhLength = 256;
}
- else if (len == 117) {
+ else if (len == 117) { // Dh3k
dhLength = 384;
}
- else if (len == 37) {
+ else if (len == 37) { // EC256
dhLength = 64;
}
- else if (len == 45) {
+ else if (len == 45) { // EC384
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/zrtp/ZrtpPacketError.cpp
index a9d881e..94d4dc1 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
index 3a30977..d0d0f33 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
index 6635fa3..bc885ef 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -19,6 +19,7 @@
* Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
*/
+#include <ctype.h>
#include <libzrtpcpp/ZrtpPacketHello.h>
@@ -62,8 +63,6 @@
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);
@@ -102,14 +101,25 @@
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);
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;
@@ -125,3 +135,14 @@
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/zrtp/ZrtpPacketHelloAck.cpp
index 2d752b7..2849f2d 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
index 9a1f90f..b79e4ac 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -30,7 +30,7 @@
setZrtpId();
setLength((sizeof(PingPacket_t) / ZRTP_WORD_SIZE) - 1);
setMessageType((uint8_t*)PingMsg);
- setVersion((uint8_t*)zrtpVersion);
+ setVersion((uint8_t*)zrtpVersion_11); // TODO: fix version string after clarification
}
ZrtpPacketPing::ZrtpPacketPing(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
index 2331640..0bee991 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -30,7 +30,7 @@
setZrtpId();
setLength((sizeof(PingAckPacket_t) / ZRTP_WORD_SIZE) - 1);
setMessageType((uint8_t*)PingAckMsg);
- setVersion((uint8_t*)zrtpVersion);
+ setVersion((uint8_t*)zrtpVersion_11); // TODO: fix version string after clarification
}
ZrtpPacketPingAck::ZrtpPacketPingAck(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
index 6ff0c7a..a531e2f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-20011 Werner Dittmann
+ Copyright (C) 2006-20013 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
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
index d132e28..c8b7f54 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp b/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
index 9e838da..fef847e 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
@@ -119,12 +119,15 @@
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;
@@ -158,6 +161,10 @@
// 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);
@@ -679,9 +686,9 @@
clientIdString = id;
}
-std::string ZrtpQueue::getHelloHash() {
+std::string ZrtpQueue::getHelloHash(int32_t index) {
if (zrtpEngine != NULL)
- return zrtpEngine->getHelloHash();
+ return zrtpEngine->getHelloHash(index);
else
return std::string();
}
@@ -811,6 +818,21 @@
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/ZrtpSdesStream.cpp b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
index a987032..a6756af 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
@@ -1,7 +1,28 @@
+/*
+ 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>
@@ -11,17 +32,16 @@
#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
-/*
- * These functions support 256 bit encryption algorithms.
- */
-#define MAX_KEY_LEN 32
-#define MAX_SALT_LEN 14
-
+// 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):
*
@@ -85,6 +105,19 @@
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;
@@ -101,17 +134,18 @@
/* 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, aes1, 40, (uint64_t)1<<48, 1<<31
+ 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, aes1, 40, (uint64_t)1<<48, 1<<31
+ 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) {
+ sendSrtcp(NULL), srtcpIndex(0), recvZrtpTunnel(0), sendZrtpTunnel(0), cryptoMixHashLength(0),
+ cryptoMixHashType(MIX_NONE) {
}
ZrtpSdesStream::~ZrtpSdesStream() {
@@ -130,6 +164,12 @@
delete recvSrtcp;
recvSrtp = NULL;
+
+ delete recvZrtpTunnel;
+ recvZrtpTunnel = NULL;
+
+ delete sendZrtpTunnel;
+ sendZrtpTunnel = NULL;
}
bool ZrtpSdesStream::createSdes(char *cryptoString, size_t *maxLen, bool sipInvite) {
@@ -152,13 +192,13 @@
state = OUT_PROFILE_READY;
}
else {
+ createSrtpContexts(sipInvite);
state = SDES_SRTP_ACTIVE;
}
return s;
-
}
-bool ZrtpSdesStream::parseSdes(char *cryptoString, size_t length, bool sipInvite) {
+bool ZrtpSdesStream::parseSdes(const char *cryptoString, size_t length, bool sipInvite) {
if (sipInvite) {
if (state != OUT_PROFILE_READY)
@@ -179,6 +219,7 @@
// 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 {
@@ -217,6 +258,36 @@
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)
@@ -235,8 +306,70 @@
return knownSuites[suite].cipher;
}
-const char* ZrtpSdesStream::getAuthAlgo(){
- return knownSuites[suite].tagLength;
+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
@@ -284,15 +417,213 @@
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) {
- uint8_t keySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4] = {0}; /* Some buffer for random data, multiple of 4 */
char b64keySalt[(MAX_KEY_LEN + MAX_SALT_LEN) * 2] = {'\0'};
uint32_t sidx;
int32_t b64Len;
- /* Lookup crypto suite parameters */
- for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {
+ for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) { // Lookup crypto suite parameters
if (knownSuites[sidx].suite == suite)
break;
}
@@ -300,45 +631,29 @@
return false;
}
suiteParam *pSuite = &knownSuites[sidx];
- _random(keySalt, sizeof(keySalt));
+ _random(localKeySalt, sizeof(localKeySalt));
AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
- int authn = SrtpAuthenticationSha1Hmac;
- int authKeyLen = pSuite->authKeyLength / 8;
- int tagLength = auth.getKeylen() / 8;
+ 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
- int cipher = SrtpEncryptionAESCM;
+ localCipher = SrtpEncryptionAESCM;
- int keyLenBytes = pSuite->keyLength / 8;
- int saltLenBytes = pSuite->saltLength / 8;
-
- sendSrtp = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- keySalt, // Master Key
- keyLenBytes, // Master Key length
- &keySalt[keyLenBytes], // Master Salt
- saltLenBytes, // Master Salt length
- keyLenBytes, // encryption keylen
- authKeyLen, // authentication key len (HMAC key lenght)
- saltLenBytes, // session salt len
- tagLength); // authentication tag len
- sendSrtp->deriveSrtpKeys(0L);
+ localKeyLenBytes = pSuite->keyLength / 8;
+ localSaltLenBytes = pSuite->saltLength / 8;
if (tag == -1)
tag = 1;
- /* Get B64 code for master key and master salt */
- b64Len = b64Encode(keySalt, keyLenBytes + saltLenBytes, b64keySalt, sizeof(b64keySalt));
+ // 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);
- memset(keySalt, 0, sizeof(keySalt));
return true;
}
@@ -346,7 +661,6 @@
int elements, i;
int charsScanned;
int mkiLength = 0;
- uint8_t keySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4] = {0};
uint32_t sidx;
char cryptoString[MAX_CRYPT_STRING_LEN+1] = {'\0'};
@@ -362,28 +676,22 @@
length = strlen(cryptoStr);
if (length > MAX_CRYPT_STRING_LEN) {
-// fprintf(stderr, "parseCreateSdesProfile() crypto string too long: %ld, maximum: %d\n", length, MAX_CRYPT_STRING_LEN);
return false;
}
- /* make own copy, null terminated */
- memcpy(cryptoString, cryptoStr, length);
+ memcpy(cryptoString, cryptoStr, length); // make own copy, null terminated
*outTag = -1;
elements = sscanf(cryptoString, parseCrypto, outTag, suiteName, keyParams, &charsScanned);
- /* Do we have enough elements in the string */
- if (elements < minElementsCrypto) {
-// fprintf(stderr, "parseCreateSdesProfile() to few elements in crypto string: %d, expected: %d\n", elements, minElementsCrypto);
+ if (elements < minElementsCrypto) { // Do we have enough elements in the string
return false;
}
- /* Lookup crypto suite */
- for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {
+ 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)) {
-// fprintf(stderr, "parseCreateSdesProfile() unsupported crypto suite: %s\n", suiteName);
return false;
}
suiteParam *pSuite = &knownSuites[sidx];
@@ -392,57 +700,30 @@
/* Now scan the key parameters */
elements = sscanf(keyParams, parseKeyParam, keySaltB64, lifetime, mkiVal, &mkiLength);
- /* Currently only one we only accept key||salt B64 string, no other parameters */
- if (elements != minElementsKeyParam) {
-// fprintf(stderr, "parseCreateSdesProfile() wrong number of parameters in key parameters: %d, expected: %d\n",
-// elements, minElementsKeyParam);
+ if (elements != minElementsKeyParam) { // Currently we only accept key||salt B64 string, no other parameters
return false;
}
- int keyLenBytes = pSuite->keyLength / 8;
- int saltLenBytes = pSuite->saltLength / 8;
+ remoteKeyLenBytes = pSuite->keyLength / 8;
+ remoteSaltLenBytes = pSuite->saltLength / 8;
- /* Check if key||salt B64 string hast the correct length */
- if (strlen(keySaltB64) != pSuite->b64length) {
-// fprintf(stderr, "parseCreateSdesProfile() B64 key||salt string length does not match: %ld, expected: %d\n",
-// strlen(keySaltB64), pSuite->b64length);
+ 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);
- i = b64Decode(keySaltB64, pSuite->b64length, keySalt, keyLenBytes + saltLenBytes);
-
- /* Did the B64 decode deliver enough data for key||salt */
- if (i != (keyLenBytes + saltLenBytes)) {
-// fprintf(stderr, "parseCreateSdesProfile() B64 key||salt binary data length does not match: %d, expected: %d\n",
-// i, keyLenBytes + saltLenBytes);
+ if (i != (remoteKeyLenBytes + remoteSaltLenBytes)) { // Did the B64 decode delivered enough data for key||salt
return false;
}
AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
- int authn = SrtpAuthenticationSha1Hmac;
- int authKeyLen = pSuite->authKeyLength / 8;
- int tagLength = auth.getKeylen() / 8;
+ 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
- int cipher = SrtpEncryptionAESCM;
-
- recvSrtp = new CryptoContext(0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- keySalt, // Master Key
- keyLenBytes, // Master Key length
- &keySalt[keyLenBytes], // Master Salt
- saltLenBytes, // Master Salt length
- keyLenBytes, // encryption keylen
- authKeyLen, // authentication key len (HMAC key lenght)
- saltLenBytes, // session salt len
- tagLength); // authentication tag len
- recvSrtp->deriveSrtpKeys(0L);
-
- memset(keySalt, 0, sizeof(keySalt));
+ remoteCipher = SrtpEncryptionAESCM;
return true;
}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp b/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
index 74dfb04..2c46a4f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2008 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -46,14 +46,9 @@
};
-ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
- parent = p;
- secSubstate = Normal;
+ZrtpStateClass::ZrtpStateClass(ZRtp *p) : parent(p), commitPkt(NULL), multiStream(false), secSubstate(Normal), sentVersion(0) {
engine = new ZrtpStates(states, numberOfStates, Initial);
- commitPkt = NULL;
- multiStream = false;
-
// Set up timers according to ZRTP spec
T1.start = 50;
T1.maxResend = 20;
@@ -99,10 +94,10 @@
if (!inState(WaitErrorAck)) {
uint16_t totalLength = *(uint16_t*)(pkt+2);
totalLength = zrtpNtohs(totalLength) * ZRTP_WORD_SIZE;
- totalLength += 12 + sizeof(uint32_t); // !2 bytes is fixed header, uint32_t is CRC
+ 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, 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;
@@ -128,7 +123,9 @@
else if (first == 'p' && middle == ' ' && last == ' ') {
ZrtpPacketPing ppkt(pkt);
ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);
- parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
+ if (ppktAck != NULL) { // ACK only to valid PING packet, otherwise ignore it
+ parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
+ }
parent->synchLeave();
return;
}
@@ -157,10 +154,11 @@
DEBUGOUT((cout << "Checking for match in Initial.\n"));
if (event->type == ZrtpInitial) {
- ZrtpPacketHello* hello = parent->prepareHello();
+ ZrtpPacketHello* hello = parent->prepareHello();
+ sentVersion = hello->getVersionInt();
- // 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
@@ -170,7 +168,7 @@
timerFailed(SevereNoTimer); // returns to state Initial
return;
}
- nextState(Detect);
+ nextState(Detect);
}
}
@@ -238,6 +236,8 @@
* - 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,7 +247,8 @@
}
/*
* Hello:
- * - send HelloAck packet to acknowledge the received Hello packet
+ * - send HelloAck packet to acknowledge the received Hello packet if versions match.
+ * Otherweise negotiate ZRTP versions.
* - 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.
@@ -256,7 +257,58 @@
* - 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))) {
@@ -265,7 +317,6 @@
}
// 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);
@@ -292,7 +343,7 @@
nextState(Detect);
}
}
- // If application call zrtpStart() to restart discovery
+ // If application calls zrtpStart() to restart discovery
else if (event->type == ZrtpInitial) {
cancelTimer();
if (!parent->sendPacketZRTP(sentPacket)) {
@@ -360,36 +411,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:
@@ -421,7 +472,7 @@
* - switch to state WaitDHPart2 and wait for peer's DHPart2
* - don't start timer, we are responder
*/
- if (first == 'c') {
+ if (first == 'c' && last == ' ') {
cancelTimer();
ZrtpPacketCommit cpkt(pkt);
@@ -459,7 +510,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
@@ -561,7 +612,7 @@
* - Initiator role, thus start timer T2 to monitor timeout for Commit
*/
- if (first == 'h') {
+ if (first == 'h' && last == ' ') {
// Parse peer's packet data into a Hello packet
ZrtpPacketHello hpkt(pkt);
ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
@@ -611,7 +662,7 @@
DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
- char *msg, first;
+ char *msg, first, last;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -620,12 +671,13 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
+ last = tolower(*(msg+7));
/*
* Hello:
* - resend HelloAck
* - stay in WaitCommit
*/
- if (first == 'h') {
+ if (first == 'h' && last == ' ') {
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
}
@@ -638,7 +690,7 @@
* - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode
* - don't start timer, we are responder
*/
- if (first == 'c') {
+ if (first == 'c' && last == ' ') {
ZrtpPacketCommit cpkt(pkt);
if (!multiStream) {
@@ -706,7 +758,7 @@
DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
- char *msg, first, last;
+ char *msg, first, middle, last, secondLast;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -715,7 +767,9 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
+ middle = tolower(*(msg+4));
last = tolower(*(msg+7));
+ secondLast = tolower(*(msg+6));
/*
* HelloAck or Hello:
@@ -723,7 +777,7 @@
* ignore it
* - no switch in state, leave timer as it is
*/
- if (first == 'h' && (last =='k' || last == ' ')) {
+ if (first == 'h' && middle == 'o' && (last =='k' || last == ' ')) {
return;
}
@@ -748,6 +802,11 @@
}
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
@@ -800,7 +859,7 @@
* - switch to WaitConfirm1
* - start timer to resend DHPart2 if necessary, we are Initiator
*/
- if (first == 'd') {
+ if (first == 'd' && secondLast == '1') {
cancelTimer();
sentPacket = NULL;
ZrtpPacketDHPart dpkt(pkt);
@@ -832,6 +891,11 @@
return;
}
+ /*
+ * Confirm1 and multi-stream mode
+ * - switch off resending commit
+ * - prepare Confirm2
+ */
if (multiStream && (first == 'c' && last == '1')) {
cancelTimer();
ZrtpPacketConfirm cpkt(pkt);
@@ -902,7 +966,7 @@
DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
- char *msg, first;
+ char *msg, first, secondLast, last;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -911,12 +975,14 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
+ last = tolower(*(msg+7));
+ secondLast = tolower(*(msg+6));
/*
* Commit:
* - resend DHPart1
* - stay in state
*/
- if (first == 'c') {
+ if (first == 'c' && last == ' ') {
if (!parent->sendPacketZRTP(sentPacket)) {
return sendFailed(); // returns to state Initial
}
@@ -928,7 +994,7 @@
* - switch to WaitConfirm2
* - No timer, we are responder
*/
- if (first == 'd') {
+ if (first == 'd' && secondLast == '2') {
ZrtpPacketDHPart dpkt(pkt);
ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);
@@ -1069,7 +1135,7 @@
DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
- char *msg, first, last;
+ char *msg, first, secondLast, last;
uint8_t *pkt;
uint32_t errorCode = 0;
@@ -1078,6 +1144,7 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
+ secondLast = tolower(*(msg+6));
last = tolower(*(msg+7));
/*
@@ -1085,7 +1152,7 @@
* - resend Confirm1 packet
* - stay in state
*/
- if (first == 'd' || (multiStream && (first == 'c' && last == ' '))) {
+ if ((first == 'd' && secondLast == '2') || (multiStream && (first == 'c' && last == ' '))) {
if (!parent->sendPacketZRTP(sentPacket)) {
sendFailed(); // returns to state Initial
}
@@ -1151,7 +1218,7 @@
DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
- char *msg, first;
+ char *msg, first, last;
uint8_t *pkt;
if (event->type == ZrtpPacket) {
@@ -1159,12 +1226,13 @@
msg = (char *)pkt + 4;
first = tolower(*msg);
+ last = tolower(*(msg+7));
/*
* ConfAck:
* - Switch off resending Confirm2
* - switch to SecureState
*/
- if (first == 'c') {
+ if (first == 'c' && last == 'k') {
cancelTimer();
sentPacket = NULL;
// Receiver was already enabled after sending Confirm2 packet
@@ -1208,44 +1276,45 @@
void ZrtpStateClass::evWaitClearAck(void) {
DEBUGOUT((cout << "Checking for match in ClearAck.\n"));
- 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);
- }
+// 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);
+// }
}
@@ -1349,7 +1418,7 @@
}
/*
* GoClear received, handle it. TODO fix go clear handling
- */
+ *
if (first == 'g' && last == 'r') {
ZrtpPacketGoClear gpkt(pkt);
ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);
@@ -1359,12 +1428,18 @@
}
// TODO Timeout to resend clear ack until user user confirmation
}
+ */
}
else if (event->type == Timer) {
// Ignore stray timeout in this state
;
}
- else { // unknown Event type for this state (covers Error and ZrtpClose)
+ // 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;
sentPacket = NULL;
parent->srtpSecretsOff(ForSender);
parent->srtpSecretsOff(ForReceiver);
diff --git a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
index 93e2ccf..ecf5b6d 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2008 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -22,8 +22,9 @@
#include <libzrtpcpp/ZrtpConfigure.h>
// 1
// 1234567890123456
-char clientId[] = "GNU ZRTP 3.0.0 "; // 16 chars max.
-char zrtpVersion[] = "1.10"; // must be 4 chars
+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
/**
*
*/
@@ -69,6 +70,8 @@
char s256[] = "S256";
char s384[] = "S384";
+char skn2[] = "SKN2";
+char skn3[] = "SKN3";
const char* mandatoryHash = s256;
char aes3[] = "AES3";
@@ -83,6 +86,8 @@
char ec25[] = "EC25";
char dh3k[] = "DH3k";
char ec38[] = "EC38";
+char e255[] = "E255";
+char e414[] = "E414";
char mult[] = "Mult";
const char* mandatoryPubKey = dh3k;
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp b/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
index 43a3306..f3042f8 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 by Werner Dittmann
+ 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
@@ -29,8 +29,7 @@
* files in the program, then also delete it here.
*/
-/** Copyright (C) 2012
- *
+/**
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h b/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
index b121893..7223bdf 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
+++ b/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
index cb17b8f..1c743d2 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
index 19acb6e..066035f 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
index 0b6e213..bc8897a 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006, 2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
index a53a674..a0ecc65 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
index 1015c44..b20bfe6 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
index c7d7c57..c26a23c 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
index 955c40b..1e3ceb7 100644
--- a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Werner Dittmann
+ 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
@@ -124,7 +124,7 @@
hmacSha256Init(&ctx, key, keyLength);
hmacSha256Update(&ctx, data, dataLength);
hmacSha256Final(&ctx, mac);
- *macLength = SHA256_BLOCK_SIZE;
+ *macLength = SHA256_DIGEST_SIZE;
}
void hmac_sha256(uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
@@ -140,7 +140,7 @@
dataChunckLength ++;
}
hmacSha256Final(&ctx, mac);
- *macLength = SHA256_BLOCK_SIZE;
+ *macLength = SHA256_DIGEST_SIZE;
}
void* createSha256HmacContext(uint8_t* key, int32_t keyLength)
@@ -159,7 +159,7 @@
hmacSha256Reset(pctx);
hmacSha256Update(pctx, data, dataLength);
hmacSha256Final(pctx, mac);
- *macLength = SHA256_BLOCK_SIZE;
+ *macLength = SHA256_DIGEST_SIZE;
}
void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
@@ -174,7 +174,7 @@
dataLength++;
}
hmacSha256Final(pctx, mac);
- *macLength = SHA256_BLOCK_SIZE;
+ *macLength = SHA256_DIGEST_SIZE;
}
void freeSha256HmacContext(void* ctx)
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
index 40b4487..c7a7abd 100644
--- a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
@@ -124,7 +124,7 @@
hmacSha384Init(&ctx, key, keyLength);
hmacSha384Update(&ctx, data, dataLength);
hmacSha384Final(&ctx, mac);
- *macLength = SHA384_BLOCK_SIZE;
+ *macLength = SHA384_DIGEST_SIZE;
}
void hmac_sha384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
@@ -140,7 +140,7 @@
dataChunckLength ++;
}
hmacSha384Final(&ctx, mac);
- *macLength = SHA384_BLOCK_SIZE;
+ *macLength = SHA384_DIGEST_SIZE;
}
void* createSha384HmacContext(uint8_t* key, int32_t keyLength)
@@ -159,7 +159,7 @@
hmacSha384Reset(pctx);
hmacSha384Update(pctx, data, dataLength);
hmacSha384Final(pctx, mac);
- *macLength = SHA384_BLOCK_SIZE;
+ *macLength = SHA384_DIGEST_SIZE;
}
void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
@@ -174,7 +174,7 @@
dataLength++;
}
hmacSha384Final(pctx, mac);
- *macLength = SHA384_BLOCK_SIZE;
+ *macLength = SHA384_DIGEST_SIZE;
}
void freeSha384HmacContext(void* ctx)
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp b/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
index 17961c3..2c5c8de 100755
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006 Werner Dittmann
+ 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 General Public License as published by
+ it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@@ -18,19 +18,16 @@
#include <stdio.h>
#include <openssl/evp.h>
-#include <libzrtpcpp-config.h>
+#include <config.h>
-#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
-#undef _MSWINDOWS_
-#define _MSWINDOWS_
+#ifdef _MSWINDOWS_
#include <windows.h>
#endif
-
#if defined SOLARIS && !defined HAVE_PTHREAD_H
#include <synch.h>
#include <thread.h>
#endif
-#if !defined(_MSWINDOWS_) && !defined SOLARIS
+#if !defined _MSWINDOWS_ && !defined SOLARIS
#include <pthread.h>
#endif
@@ -74,7 +71,6 @@
}
#ifdef _MSWINDOWS_
-#define __LOCKING
static HANDLE *lock_cs;
@@ -112,8 +108,7 @@
#endif /* OPENSSL_SYS_WIN32 */
-#if defined SOLARIS && !defined HAVE_PTHREAD_H && !defined(_MSWINDOWS)
-#define __LOCKING
+#if defined SOLARIS && !defined HAVE_PTHREAD_H
static mutex_t *lock_cs;
static long *lock_count;
@@ -180,7 +175,6 @@
#endif /* SOLARIS */
-#ifndef __LOCKING
static pthread_mutex_t* lock_cs;
static long* lock_count;
@@ -239,4 +233,4 @@
return(ret);
}
*/
-#endif
+
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.c b/jni/libzrtp/sources/zrtp/crypto/sha2.c
index fccd1d2..22761f3 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.c
+++ b/jni/libzrtp/sources/zrtp/crypto/sha2.c
@@ -754,7 +754,7 @@
}
}
-INT_RETURN sha2(unsigned char hval[], unsigned long size,
+INT_RETURN sha2_all(unsigned char hval[], unsigned long size,
const unsigned char data[], unsigned long len)
{ sha2_ctx cx[1];
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.h b/jni/libzrtp/sources/zrtp/crypto/sha2.h
index 91d0745..1ad3889 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.h
+++ b/jni/libzrtp/sources/zrtp/crypto/sha2.h
@@ -140,7 +140,7 @@
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(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
+INT_RETURN sha2_all(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha256.h b/jni/libzrtp/sources/zrtp/crypto/sha256.h
index 959a620..36127b9 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.h
+++ b/jni/libzrtp/sources/zrtp/crypto/sha256.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.h b/jni/libzrtp/sources/zrtp/crypto/sha384.h
index 6cb7a70..d4ccce5 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.h
+++ b/jni/libzrtp/sources/zrtp/crypto/sha384.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp b/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
new file mode 100644
index 0000000..94cff63
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
@@ -0,0 +1,100 @@
+/*
+ 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
new file mode 100644
index 0000000..6d4e722
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skein256.h
@@ -0,0 +1,146 @@
+/*
+ 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
new file mode 100644
index 0000000..1dbe608
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
@@ -0,0 +1,103 @@
+/*
+ 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
new file mode 100644
index 0000000..61fd64e
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skein384.h
@@ -0,0 +1,146 @@
+/*
+ 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
new file mode 100644
index 0000000..b4234e5
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
@@ -0,0 +1,73 @@
+/*
+ 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
new file mode 100644
index 0000000..e87a1e1
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
@@ -0,0 +1,91 @@
+/*
+ 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
new file mode 100644
index 0000000..57c7ad1
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
@@ -0,0 +1,76 @@
+/*
+ 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
new file mode 100644
index 0000000..2065899
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
@@ -0,0 +1,91 @@
+/*
+ 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/twoCFB.h b/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
index e063a35..595d19d 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
+++ b/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
index e602dd3..d718f24 100644
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
@@ -62,7 +62,7 @@
typedef struct _dhCtx {
BigNum privKey;
BigNum pubKey;
- NistECpCurve curve;
+ EcCurve curve;
EcPoint pubPoint;
} dhCtx;
@@ -202,6 +202,12 @@
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;
}
@@ -246,6 +252,16 @@
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;
}
}
@@ -267,6 +283,11 @@
case EC38:
ecFreeCurveNistECp(&tmpCtx->curve);
break;
+
+ case E255:
+ case E414:
+ ecFreeCurvesCurve(&tmpCtx->curve);
+ break;
}
}
@@ -300,7 +321,7 @@
return length;
}
- if (pkType == EC25 || pkType == EC38) {
+ if (pkType == EC25 || pkType == EC38 || pkType == E414) {
int32_t len = getPubKeySize() / 2;
EcPoint pub;
@@ -319,6 +340,23 @@
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;
}
@@ -338,7 +376,10 @@
case EC25:
case EC38:
- return ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey);
+ case E255:
+ case E414:
+ while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))
+ ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
}
return 0;
}
@@ -359,6 +400,13 @@
case EC38:
return 48;
break;
+
+ case E255:
+ return 32;
+ break;
+ case E414:
+ return 52;
+ break;
}
return 0;
}
@@ -369,9 +417,11 @@
if (pkType == DH2K || pkType == DH3K)
return bnBytes(&tmpCtx->pubKey);
- if (pkType == EC25 || pkType == EC38)
- return bnBytes(tmpCtx->curve.p) * 2;
+ 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;
}
@@ -391,13 +441,18 @@
return size;
}
- if (pkType == EC25 || pkType == EC38) {
+ 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;
}
@@ -405,49 +460,22 @@
{
/* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */
- if (pkType == EC25 || pkType == EC38) {
+ if (pkType == EC25 || pkType == EC38 || pkType == E414) {
- struct BigNum t1, t2;
dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
EcPoint pub;
- int ret = 0;
INIT_EC_POINT(&pub);
int32_t len = getPubKeySize() / 2;
- bnBegin(&t1);
- bnBegin(&t2);
-
bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
- /* Represent point at infinity by (0, 0), make sure it's not that */
- if (bnCmpQ(pub.x, 0) == 0 && bnCmpQ(pub.y, 0) == 0) {
- goto fail;
- }
- /* Check that coordinates are within range */
- if (bnCmpQ(pub.x, 0) < 0 || bnCmp(pub.x, tmpCtx->curve.p) >= 0) {
- goto fail;
- }
- if (bnCmpQ(pub.y, 0) < 0 || bnCmp(pub.y, tmpCtx->curve.p) >= 0) {
- goto fail;
- }
- /* Check that point satisfies EC equation y^2 = x^3 - 3x + b, mod P */
- bnSquareMod_(&t1, pub.y, tmpCtx->curve.p);
- bnSquareMod_(&t2, pub.x, tmpCtx->curve.p);
- bnSubQMod_(&t2, 3, tmpCtx->curve.p);
- bnMulMod_(&t2, &t2, pub.x, tmpCtx->curve.p);
- bnAddMod_(&t2, tmpCtx->curve.b, tmpCtx->curve.p);
- if (bnCmp (&t1, &t2) != 0) {
- goto fail;
- }
- ret = 1;
+ return ecCheckPubKey(&tmpCtx->curve, &pub);
+ }
- fail:
- FREE_EC_POINT(&pub);
- bnEnd(&t1);
- bnEnd(&t2);
- return ret;
+ if (pkType == E255) {
+ return 1;
}
BigNum pubKeyOther;
@@ -481,16 +509,16 @@
switch (pkType) {
case DH2K:
return dh2k;
- break;
case DH3K:
return dh3k;
- break;
case EC25:
return ec25;
- break;
case EC38:
return ec38;
- break;
+ case E255:
+ return e255;
+ case E414:
+ return e414;
}
return NULL;
}
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
index acf0e92..d2a3a40 100644
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
+++ b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
@@ -59,6 +59,8 @@
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;
/**
diff --git a/jni/libzrtp/sources/clients/ccrtp/CcrtpTimeoutProvider.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
similarity index 100%
rename from jni/libzrtp/sources/clients/ccrtp/CcrtpTimeoutProvider.h
rename to jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
index 8f471a6..2ba1de6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -161,9 +161,9 @@
/**
* @brief Clean the cache.
*
- * This method cleans the cache and discards all information about remote peers.
- * The method does not delete the local (own) ZID. To delete local ZID information
- * the user must delete the database base.
+ * 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;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
index 6b1d70b..7aa6dd0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
index 9d43fde..7b264e8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
index f3d804e..c46fc24 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -19,7 +19,7 @@
#define _ZIDRECORD_H_
#include <stdint.h>
-
+#include <common/osSpecifics.h>
/**
* @file ZIDRecord.h
* @brief ZID cache record management
@@ -32,19 +32,6 @@
* @{
*/
-#ifndef __EXPORT
- #if __GNUC__ >= 4
- #define __EXPORT __attribute__ ((visibility("default")))
- #define __LOCAL __attribute__ ((visibility("hidden")))
- #elif defined _WIN32 || defined __CYGWIN__
- #define __EXPORT __declspec(dllimport)
- #define __LOCAL
- #else
- #define __EXPORT
- #define __LOCAL
- #endif
-#endif
-
/**
* These length are fixed for ZRTP. See RFC 6189.
*/
@@ -65,6 +52,12 @@
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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
index 28287d9..111b4ed 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
index 579a430..74cc8a0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
index 417a892..a20b599 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -51,6 +51,15 @@
#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;
@@ -108,6 +117,14 @@
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
@@ -219,17 +236,25 @@
/**
* 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 containing the Hello hash value as hex-digits. The
- * hello hash is available immediately after class instantiation.
+ * 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()
*/
- std::string getHelloHash();
+ std::string getHelloHash(int index);
/**
* Get the peer's ZRTP Hello Hash data.
@@ -490,6 +515,28 @@
*/
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;
@@ -612,7 +659,6 @@
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
@@ -770,7 +816,9 @@
/**
* Pre-initialized packets.
*/
- ZrtpPacketHello zrtpHello;
+ ZrtpPacketHello zrtpHello_11;
+ ZrtpPacketHello zrtpHello_12; // Prepare for ZRTP protocol version 1.2
+
ZrtpPacketHelloAck zrtpHelloAck;
ZrtpPacketConf2Ack zrtpConf2Ack;
ZrtpPacketClearAck zrtpClearAck;
@@ -786,12 +834,24 @@
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
*/
uint8_t randomIV[16];
@@ -938,20 +998,75 @@
bool checkMultiStream(ZrtpPacketHello* hello);
/**
- * Checks if Hello packet contains a strong (384bit) hash and returns it.
+ * 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);
+ AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName);
/**
- * Checks if Hello packet offers a strong (256bit) symmetric cipher.
+ * Checks if Hello packet offers a strong (256bit) symmetric cipher based on selection policy.
*
- * The method returns the first strong cipher offered in the Hello packet.
+ * 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);
+ 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
@@ -965,6 +1080,8 @@
void computeSharedSecretSet(ZIDRecord *zidRec);
+ void computeAuxSecretIds();
+
void computeSRTPKeys();
void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
@@ -1345,8 +1462,10 @@
*
* @param id
* The client's id
+ * @param hpv
+ * Pointer to hello packet version structure.
*/
- void setClientId(std::string id);
+ void setClientId(std::string id, HelloPacketVersion* hpv);
};
/**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
index 19aebb0..0ad5b95 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
@@ -1,9 +1,9 @@
/*
This file defines the GNU ZRTP C-to-C++ wrapper.
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2013 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
+ 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.
@@ -565,7 +565,7 @@
* @returns
* Pointer to the ZrtpContext
*/
- ZrtpContext* zrtp_CreateWrapper();
+ ZrtpContext* zrtp_CreateWrapper(void);
/**
* Initialize the ZRTP protocol engine.
@@ -782,21 +782,28 @@
*
* 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. Refer to ZRTP specification, chapter 8.
+ * 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.
*
- * <b>NOTE: An application may call this method if it needs this information.
- * Usually it is not necessary.</b>
+ * Refer to ZRTP specification, chapter 8.
+ *
+ * @param index
+ * Hello hash of the Hello packet identfied by index. Index must be 0 <= index < zrtp_getNumberSupportedVersions().
*
* @param zrtpContext
* Pointer to the opaque ZrtpContext structure.
+ *
* @return
- * 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
+ * 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
* hello hash C-string anymore.
+ *
+ * @see zrtp_getNumberSupportedVersions()
*/
- char* zrtp_getHelloHash(ZrtpContext* zrtpContext);
+ char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index);
/**
* Get the peer's ZRTP Hello Hash data.
@@ -1070,7 +1077,27 @@
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/zrtp/libzrtpcpp/ZrtpCallback.h
index 957c4dd..0ad18a9 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -28,19 +28,7 @@
#include <string>
#include <stdint.h>
#include <libzrtpcpp/ZrtpCodes.h>
-
-#ifndef __EXPORT
- #if __GNUC__ >= 4
- #define __EXPORT __attribute__ ((visibility("default")))
- #define __LOCAL __attribute__ ((visibility("hidden")))
- #elif defined _WIN32 || defined __CYGWIN__
- #define __EXPORT __declspec(dllimport)
- #define __LOCAL
- #else
- #define __EXPORT
- #define __LOCAL
- #endif
-#endif
+#include <common/osSpecifics.h>
/**
* This enum defines which role a ZRTP peer has.
@@ -58,6 +46,7 @@
* </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;
@@ -129,9 +118,10 @@
* ZRTP calls this method to send a ZRTP packet via the RTP session.
*
* @param data
- * Points to ZRTP packet to send.
+ * Points to ZRTP packet to send. The packet already contains a 4 bytes
+ * storage at the end to store CRC.
* @param length
- * The length in bytes of the data
+ * The length in bytes of the data, including the CRC storage.
* @return
* zero if sending failed, one if packet was send
*/
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
index dd739e0..098ec06 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
@@ -1,9 +1,9 @@
/*
This class maps the ZRTP C++ callback methods to C callback methods.
- Copyright (C) 2010 Werner Dittmann
+ Copyright (C) 2010-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
index b35d47b..1a7dd5f 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
@@ -1,10 +1,10 @@
/** @file ZrtpCodes.h
*/
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ it under the terms of the Lesser GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -90,14 +90,15 @@
* Sub-codes for Warning
*/
enum WarningCodes {
- WarningDHAESmismatch = 1, //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096
+ WarningDHAESmismatch = 1, //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded
WarningGoClearReceived, //!< Received a GoClear message
- WarningDHShort, //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096
+ WarningDHShort, //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded
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
+ 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
};
/**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
index 896a85f..bb78cef 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2009 - 2010 Werner Dittmann
+ Copyright (C) 2009 - 2013 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
+ 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.
@@ -315,6 +315,14 @@
~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.
*/
@@ -510,6 +518,9 @@
/// 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;
@@ -532,6 +543,8 @@
void printConfiguredAlgos(std::vector<AlgorithmEnum* >& a);
+ Policy selectionPolicy;
+
protected:
public:
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
index ad57edd..49eec83 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
index 11b7930..a5826c7 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -38,12 +38,8 @@
#include <string.h>
#include <stdlib.h>
-#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
#include <common/osSpecifics.h>
+
#include <libzrtpcpp/zrtpPacket.h>
#include <libzrtpcpp/ZrtpTextData.h>
#include <libzrtpcpp/ZrtpConfigure.h>
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
index 992f6d8..91ca4c4 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
index b23b23d..4b6e1eb 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -31,6 +31,11 @@
#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.
*
@@ -48,6 +53,11 @@
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();
@@ -90,6 +100,10 @@
/// 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/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
index a7c2567..a6f85f5 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
index e3ff85b..283861d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -84,6 +84,11 @@
/// 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; }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
index d0ea4ba..08737a5 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -79,6 +79,9 @@
/// 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/zrtp/libzrtpcpp/ZrtpPacketError.h
index ca00ee0..679a803 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
index e64c8a6..cfd435c 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2007 - 2010 Werner Dittmann
+ Copyright (C) 2007-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
index c9a38bd..f5394af 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2012 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -85,6 +85,9 @@
/// 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; };
@@ -95,7 +98,7 @@
uint8_t* getZid() { return helloHeader->zid; };
/// Set version sting in Hello message, fixed ASCII character array
- void setVersion(uint8_t *text) { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
+ void setVersion(const 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)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
index 345a071..d3e138e 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
index 840df62..32fb2f9 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
index b795ffb..eb2924f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2009 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
index 93437e6..7fe373b 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2007 - 2010 Werner Dittmann
+ Copyright (C) 2007-2013 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
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
index 04721fa..22739ff 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2011 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -73,11 +73,14 @@
const uint8_t* getSasAlgo() {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; }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
index 7a1ee67..512d8c8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
@@ -368,20 +368,28 @@
*/
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 hex-digits. Refer
- * to ZRTP specification, chapter 9.1.
+ * 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().
*
* @return
- * 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.
+ * 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()
*/
- std::string getHelloHash();
+ std::string getHelloHash(int32_t index);
/**
* Get the peer's ZRTP Hello Hash data.
@@ -743,6 +751,20 @@
*/
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*>;
@@ -851,6 +873,7 @@
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/ZrtpSdesStream.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
index 7d36f2b..d7d2265 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
@@ -1,13 +1,107 @@
+/*
+ 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 ZrtpSdesStream {
+class __EXPORT ZrtpSdesStream {
public:
@@ -15,12 +109,12 @@
* Supported SDES crypto suites.
*/
typedef enum {
- AES_CM_128_HMAC_SHA1_32 = 1,
+ AES_CM_128_HMAC_SHA1_32 = 0,
AES_CM_128_HMAC_SHA1_80
} sdesSuites;
/**
- * SDES stream stated
+ * SDES stream state
*/
typedef enum {
STREAM_INITALIZED = 1,
@@ -29,15 +123,18 @@
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.
*
- * It is not necessary to explicitly start the SDES stream. The method initiates
- * the SRTP after it created and parsed all necessary SDES crypto strings.
- *
* @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.
*/
@@ -67,19 +164,16 @@
* @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The
* answering application's SRTP environment is now ready.
*
- * @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 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 if this is set to @c true (not zero) then the method
- * takes the necessary actions to create the crypto eonvironment
- * for the inviting SIP application. It it is zero then it handles
- * the invited case (answerer).
+ * @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.
*/
@@ -88,36 +182,67 @@
/**
* @brief Parses an SDES crypto string for the SDES/ZRTP stream.
*
- * Parses a received crypto string that the application received in a SIP INVITE
+ * Parses a SDES crypto string that the application received in a SIP INVITE
* or SIP 200 OK.
*
- * An INVITE-ing application shall call this function right after it received
+ * 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. This usually at the same point when
- * it gets the @c zrtp-hash from the SDP parameters.
- * This application's SRTP environment is now ready.
+ * @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. This is usually the same point when
- * it gets the @c zrtp-hash from the SDP parameters.
+ * @c sipInvite parameter set to @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 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 if this is set to @c true then the method
- * takes the necessary actions to create the crypto eonvironment
- * for the inviting SIP application. It it is zero then it handles
- * the invited case (answerer).
+ * @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(char *cryptoString, size_t length, bool sipInvite);
+ 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
@@ -151,7 +276,7 @@
/**
* @brief Process an outgoing RTCP packet
*
- * This function works in the same way as @c sdesZrtpProcessRtp.
+ * 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
@@ -185,7 +310,7 @@
* @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 RTCP packet
+ * @param length length of the RTP packet
*
* @param newLength to an integer that get the new length of the packet excluding SRTCP data.
*
@@ -199,7 +324,7 @@
/**
* @brief Process an incoming RTCP or SRTCP packet
*
- * This function works in the same way as @c sdesZrtpProcessSrtp.
+ * 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.
@@ -216,21 +341,64 @@
int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength);
/**
- * Return state of SDES stream.
+ * @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;}
/**
- * Return name of active cipher algorithm.
+ * @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();
/**
- * Return name of active SRTP authentication algorithm.
+ * @brief Return name of active SRTP authentication algorithm.
*
* @return point to name of authentication algorithm.
*/
@@ -244,11 +412,9 @@
/**
* @brief Create an SRTP crypto context and the according SDES crypto string.
*
- * This lower layer method creates an SRTP profile an the according 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 method also creates the internal
- * SRTP/SRTCP crypto contexts for outgoing data.
+ * 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
@@ -291,8 +457,7 @@
*
* 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. The method
- * also creates the internal SRTP/SRTCP crypto contexts for incoming data.
+ * 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.
@@ -324,6 +489,28 @@
*/
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;
@@ -333,4 +520,28 @@
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/ZrtpStateClass.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
index c1887c9..5c16313 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -161,6 +161,11 @@
*/
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/zrtp/libzrtpcpp/ZrtpStates.h
index 44662a0..e90a543 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2007 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
index 91b26c1..0be1e56 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
@@ -37,8 +37,12 @@
*
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
+
+extern char zrtpBuildInfo[];
+
extern char clientId[];
-extern char zrtpVersion[];
+extern char zrtpVersion_11[];
+extern char zrtpVersion_12[];
/**
*
@@ -87,6 +91,8 @@
extern char s256[];
extern char s384[];
+extern char skn2[];
+extern char skn3[];
extern const char* mandatoryHash;
extern char aes3[];
@@ -102,6 +108,8 @@
extern char dh3k[];
extern char ec25[];
extern char ec38[];
+extern char e255[];
+extern char e414[];
extern char mult[];
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
index 3e4871c..d3c9f9d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2008 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
index b49622e..8f33462 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
@@ -1,6 +1,19 @@
/*
- *
- */
+ 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_
@@ -279,11 +292,11 @@
/**
- * Clean the cache.
- *
- * This method cleans the cache and discards all information about remote peers.
- * The method does not delete the local (own) ZID. To delete local ZID information
- * the user must delete the database base.
+ * @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.
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
index 18ba7a1..f01fb52 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
@@ -1,8 +1,8 @@
/*
- Copyright (C) 2006-2010 Werner Dittmann
+ 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 General Public License as published by
+ 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.
diff --git a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
index d73c88d..7dc9cdf 100644
--- a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
+++ b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
@@ -1,4 +1,22 @@
/*
+ 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>
@@ -6,6 +24,7 @@
#include <stdint.h>
#include <string.h>
#include <time.h>
+#include <sqlite3.h>
#include <crypto/zrtpDH.h>
@@ -55,6 +74,8 @@
/* *****************************************************************************
* 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));";
@@ -575,11 +596,29 @@
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)
{
@@ -735,6 +774,7 @@
{
ops->openCache = openCache;
ops->closeCache = closeCache;
+ ops->cleanCache = clearCache;
ops->readLocalZid = readLocalZid;