Switch commoncpp2 to ucommon to solve dependency conflicts.

libccrtp was depending on commoncpp2, and have been replaced by a version
depending on ucommon as well.
diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
index abe0a81..7346522 100644
--- a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2008 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -133,5 +133,4 @@
 
 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 5975fc2..2c02a1e 100644
--- a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2008 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
index b097cbf..0bd91f0 100644
--- a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -29,6 +29,11 @@
     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);
 
@@ -43,7 +48,6 @@
         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 fd25dec..68a4b9c 100644
--- a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
+++ b/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -29,6 +29,11 @@
     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);
 
@@ -50,7 +55,6 @@
     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 c7d2a46..9fb8e0a 100755
--- a/jni/libzrtp/sources/zrtp/ZRtp.cpp
+++ b/jni/libzrtp/sources/zrtp/ZRtp.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -25,12 +25,6 @@
 #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>
 
@@ -58,7 +52,7 @@
     }
     fprintf(stderr, "\n");
 }
- * */
+ */
 
 /*
  * This method simplifies detection of libzrtpcpp inside Automake, configure
@@ -79,10 +73,9 @@
         callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),
         rs2Valid(false), msgShaContext(NULL), hash(NULL), cipher(NULL), pubKey(NULL), sasType(NULL), authLength(NULL),
         multiStream(false), multiStreamAvailable(false), peerIsEnrolled(false), mitmSeen(false), pbxSecretTmp(NULL),
-        enrollmentMode(false), configureAlgos(*config), zidRec(NULL), saveZidRecord(true) {
+        enrollmentMode(false), configureAlgos(*config), zidRec(NULL) {
 
     enableMitmEnrollment = config->isTrustedMitM();
-    signatureData = NULL;
     paranoidMode = config->isParanoidMode();
 
     // setup the implicit hash function pointers and length
@@ -93,8 +86,6 @@
     hmacFunctionImpl = hmac_sha256;
     hmacListFunctionImpl = hmac_sha256;
 
-    memcpy(ownZid, myZid, ZID_SIZE);        // save the ZID
-
     /*
      * Generate H0 as a random number (256 bits, 32 bytes) and then
      * the hash chain, refer to chapter 9. Use the implicit hash function.
@@ -104,40 +95,21 @@
     sha256(H1, HASH_IMAGE_SIZE, H2);        // H2
     sha256(H2, HASH_IMAGE_SIZE, H3);        // H3
 
-    // configure all supported Hello packet versions
-    zrtpHello_11.configureHello(&configureAlgos);
-    zrtpHello_11.setH3(H3);                    // set H3 in Hello, included in helloHash
-    zrtpHello_11.setZid(ownZid);
-    zrtpHello_11.setVersion((uint8_t*)zrtpVersion_11);
-
-
-    zrtpHello_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;
+    zrtpHello.configureHello(&configureAlgos);
+    zrtpHello.setH3(H3);                    // set H3 in Hello, included in helloHash
     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);
 }
 
@@ -263,7 +235,7 @@
 }
 
 ZrtpPacketHello* ZRtp::prepareHello() {
-    return currentHelloPacket;
+    return &zrtpHello;
 }
 
 ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
@@ -277,17 +249,16 @@
  */
 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????
@@ -320,15 +291,14 @@
     sasType = findBestSASType(hello);
 
     if (!multiStream) {
-        pubKey = findBestPubkey(hello);                 // Check for public key algorithm first, must set 'hash' as well
+        pubKey = findBestPubkey(hello);                 // Check for public key algorithm first, sets 'hash' as well
         if (hash == NULL) {
             *errMsg = UnsuppHashType;
             return NULL;
         }
         if (cipher == NULL)                             // public key selection may have set the cipher already
             cipher = findBestCipher(hello, pubKey);
-        if (authLength == NULL)                         // public key selection may have set the SRTP authLen already
-            authLength = findBestAuthLen(hello);
+        authLength = findBestAuthLen(hello);
         multiStreamAvailable = checkMultiStream(hello);
     }
     else {
@@ -470,7 +440,7 @@
 }
 
 /*
- * At this point we will take the role of the Responder. We have been in
+ * At this point we will take the role of the Responder. We may have been in
  * the role of the Initiator before and already sent a commit packet that
  * clashed with a commit packet from our peer. If our HVI was lower than our
  * peer's HVI then we switched to Responder and handle our peer's commit packet
@@ -482,21 +452,8 @@
 
     sendInfo(Info, InfoRespCommitReceived);
 
-    if (!commit->isLengthOk(ZrtpPacketCommit::DhExchange)) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
-
-    // Check if ZID in Commit is the same as we got in Hello
-    uint8_t tmpZid[ZID_SIZE];
-    memcpy(tmpZid, commit->getZid(), ZID_SIZE);
-    if (memcmp(peerZid, tmpZid, ZID_SIZE) != 0) {       // ZIDs do not match????
-        sendInfo(Severe, SevereProtocolError);
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
-
-    // The following code checks the hash chain according chapter 10 to detect false ZRTP packets.
+    // The following code check the hash chain according chapter 10 to detect
+    // false ZRTP packets.
     // Must use the implicit hash function.
     uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
     memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
@@ -554,8 +511,8 @@
         *errMsg = UnsuppPKExchange;
         return NULL;
     }
-    if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38 || *(int32_t*)(cp->getName()) == *(int32_t*)e414) {
-        if (!(*(int32_t*)(hash->getName()) == *(int32_t*)s384 || *(int32_t*)(hash->getName()) == *(int32_t*)skn3)) {
+    if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38) {
+        if (*(int32_t*)(hash->getName()) != *(int32_t*)s384) {
             *errMsg = UnsuppHashType;
             return NULL;
         }
@@ -571,7 +528,7 @@
     sasType = cp;
 
     // dhContext cannot be NULL - always setup during prepareCommit()
-    // check if we can use the dhContext prepared by prepareCommit(),
+    // check if we can use the dhContext prepared by prepareCOmmit(),
     // if not delete old DH context and generate new one
     // The algorithm names are 4 chars only, thus we can cast to int32_t
     if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {
@@ -583,11 +540,7 @@
 
     dhContext->getPubKeyBytes(pubKeyBytes);
 
-    // Re-compute auxSecretIDr because we changed roles *IDr with my H3, *IDi with peer's H3
     // Setup a DHPart1 packet.
-    myRole = Responder;
-    computeAuxSecretIds();                 // recompute AUX secret ids because we are now Responder, use different H3
-
     zrtpDH1.setPubKeyType(pubKey->getName());
     zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);
     zrtpDH1.setRs1Id(rs1IDr);
@@ -608,20 +561,22 @@
     zrtpDH1.setHMAC(hmac);
 
     // We are definitly responder. Save the peer's hvi for later compare.
+    myRole = Responder;
     memcpy(peerHvi, commit->getHvi(), HVI_SIZE);
 
-    // We are responder. Release the pre-computed SHA context because it was prepared for Initiator.
-    // Setup and compute for Responder.
+    // We are responder. Release a possibly pre-computed SHA context
+    // because this was prepared for Initiator. Then create a new one.
     if (msgShaContext != NULL) {
         closeHashCtx(msgShaContext, NULL);
     }
     msgShaContext = createHashCtx();
 
     // Hash messages to produce overall message hash:
-    // First the Responder's (my) Hello message, second the Commit (always Initator's), 
-    // then the DH1 message (which is always a Responder's message).
-    // Must use negotiated hash.
-    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+    // First the Responder's (my) Hello message, second the Commit
+    // (always Initator's), then the DH1 message (which is always a
+    // Responder's message).
+    // Must use negotiated hash
+    hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);
 
@@ -640,10 +595,6 @@
 
     sendInfo(Info, InfoInitDH1Received);
 
-    if (!dhPart1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // Because we are initiator the protocol engine didn't receive Commit
     // thus could not store a peer's H2. A two step SHA256 is required to
     // re-compute H3. Then compare with peer's H3 from peer's Hello packet.
@@ -682,6 +633,8 @@
     }
     dhContext->computeSecretKey(pvr, DHss);
 
+    myRole = Initiator;
+
     // We are Initiator: the Responder's Hello and the Initiator's (our) Commit
     // are already hashed in the context. Now hash the Responder's DH1 and then
     // the Initiator's (our) DH2 in that order.
@@ -714,10 +667,6 @@
 
     sendInfo(Info, InfoRespDH2Received);
 
-    if (!dhPart2->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // Because we are responder we received a Commit and stored its H2.
     // Now re-compute H2 from received H1 and compare with stored peer's H2.
     // Use implicit hash function
@@ -740,7 +689,7 @@
     // using my Hello packet and the Initiator's DHPart2 and compare with
     // hvi sent in commit packet. If it doesn't macht then a MitM attack
     // may have occured.
-    computeHvi(dhPart2, currentHelloPacket);
+    computeHvi(dhPart2, &zrtpHello);
     if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
         *errMsg = DHErrorWrongHVI;
         return NULL;
@@ -757,8 +706,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);
 
@@ -821,10 +770,6 @@
 
     sendInfo(Info, InfoRespCommitReceived);
 
-    if (!commit->isLengthOk(ZrtpPacketCommit::MultiStream)) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // The following code checks the hash chain according chapter 10 to detect
     // false ZRTP packets.
     // Use implicit hash function
@@ -895,7 +840,7 @@
     // First the Responder's (my) Hello message, second the Commit
     // (always Initator's)
     // use negotiated hash
-    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+    hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
 
     closeHashCtx(msgShaContext, messageHash);
@@ -933,10 +878,6 @@
 
     sendInfo(Info, InfoInitConf1Received);
 
-    if (!confirm1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -962,7 +903,7 @@
         return NULL;
     }
     signatureLength = confirm1->getSignatureLength();
-    if (signSasSeen && signatureLength > 0 && confirm1->isSignatureLengthOk()) {
+    if (signSasSeen && signatureLength > 0) {
         signatureData = confirm1->getSignatureData();
         callback->checkSASSignature(sasHash);
         // TODO: error handling if checkSASSignature returns false.
@@ -1015,8 +956,7 @@
             zrtpConfirm2.setPBXEnrollment();
         }
     }
-    if (saveZidRecord)
-        getZidCacheInstance()->saveRecord(zidRec);
+    getZidCacheInstance()->saveRecord(zidRec);
 
     // Encrypt and HMAC with Initiator's key - we are Initiator here
     hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
@@ -1054,10 +994,6 @@
     // don't update SAS, RS
     sendInfo(Info, InfoInitConf1Received);
 
-    if (!confirm1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -1123,10 +1059,6 @@
 
     sendInfo(Info, InfoRespConf2Received);
 
-    if (!confirm2->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -1156,7 +1088,7 @@
             return NULL;
         }
         signatureLength = confirm2->getSignatureLength();
-        if (signSasSeen && signatureLength > 0 && confirm2->isSignatureLengthOk() ) {
+        if (signSasSeen && signatureLength > 0) {
             signatureData = confirm2->getSignatureData();
             callback->checkSASSignature(sasHash);
             // TODO: error handling if checkSASSignature returns false.
@@ -1174,8 +1106,7 @@
 
         // save new RS1, this inherits the verified flag from old RS1
         zidRec->setNewRs1((const uint8_t*)newRs1);
-        if (saveZidRecord)
-            getZidCacheInstance()->saveRecord(zidRec);
+        getZidCacheInstance()->saveRecord(zidRec);
 
         // Ask for enrollment only if enabled via configuration and the
         // confirm packet contains the enrollment flag. The enrolling user
@@ -1210,10 +1141,7 @@
 }
 
 ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
-    if (epkt->getLength() < 4)
-        sendInfo(ZrtpError, CriticalSWError * -1);
-    else
-        sendInfo(ZrtpError, epkt->getErrorCode() * -1);
+    sendInfo(ZrtpError, epkt->getErrorCode() * -1);
     return &zrtpErrorAck;
 }
 
@@ -1223,8 +1151,7 @@
 }
 
 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)
@@ -1240,10 +1167,6 @@
     if (!mitmSeen || paranoidMode)
         return &zrtpRelayAck;
 
-    if (!srly->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t* hkey, *ekey;
     // If we are responder then the PBX used it's Initiator keys
     if (myRole == Responder) {
@@ -1364,7 +1287,8 @@
     if (num == 0) {
         return &zrtpHashes.getByName(mandatoryHash);
     }
-    // Build list of configured hash algorithm names.
+    // Build list of configured hash algorithm names, append mandatory algos
+    // if necessary.
     numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
     for (i = 0; i < numAlgosConf; i++) {
         algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
@@ -1378,7 +1302,8 @@
         numAlgosOffered++;
     }
 
-    // Lookup offered algos in configured algos.
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
     for (i = 0; i < numAlgosOffered; i++) {
         for (ii = 0; ii < numAlgosConf; ii++) {
             if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1429,101 +1354,85 @@
     return &zrtpSymCiphers.getByName(mandatoryCipher);
 }
 
-// We can have the non-NIST in the list of orderedAlgos even if they are not available
-// in the code (refer to ZrtpConfigure.cpp). If they are not build in they cannot appear
-// in'configureAlgos' and thus not in the intersection lists. Thus a ZRTP build that
-// does not include the non-NIST curves also works without problems.
-//
 AlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
 
-    AlgorithmEnum* peerIntersect[ZrtpConfigure::maxNoOfAlgos+1];
-    AlgorithmEnum* ownIntersect[ZrtpConfigure::maxNoOfAlgos+1];
+    int i;
+    int ii;
+    int numAlgosIntersect;
+    AlgorithmEnum* algosIntersect[ZrtpConfigure::maxNoOfAlgos+1];
+
+    int numAlgosConf;
+    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
 
     // Build list of own pubkey algorithm names, must follow the order
     // defined in RFC 6189, chapter 4.1.2.
-    const char *orderedAlgos[] = {dh2k, e255, ec25, dh3k, e414, ec38};
+    const char *orderedAlgos[] = {dh2k, ec25, dh3k, ec38};
     int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);
 
-    int numAlgosPeer = hello->getNumPubKeys();
-    if (numAlgosPeer == 0) {
-        hash = findBestHash(hello);                    // find a hash algorithm
+    int num = hello->getNumPubKeys();
+    if (num == 0) {
+        hash = &zrtpHashes.getByName(mandatoryHash);             // set mandatory hash
         return &zrtpPubKeys.getByName(mandatoryPubKey);
     }
-    // Build own list of intersecting algos, keep own order or algorithms
-    // The list must include real public key algorithms only, so skip mult-stream mode, 
-    // preshared and alike.
-    int numAlgosOwn = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
-    int numOwnIntersect = 0;
-    for (int i = 0; i < numAlgosOwn; i++) {
-        ownIntersect[numOwnIntersect] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, i);
-        if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)mult) {
+    // The list must include real public key algorithms only, so skip
+    // mult-stream mode, preshared and alike.
+    numAlgosConf = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
+    for (i = 0, ii = 0; i < numAlgosConf; i++) {
+        algosConf[ii] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, ii);
+        if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)mult) {
             continue;                               // skip multi-stream mode
         }
-        for (int ii = 0; ii < numAlgosPeer; ii++) {
-            if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)(zrtpPubKeys.getByName((const char*)hello->getPubKeyType(ii)).getName())) {
-                numOwnIntersect++;
-                break;
+        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++;
             }
         }
     }
-    // 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);
+    if (numAlgosIntersect == 0) {
+        // If we don't find a common algorithm - use the mandatory algorithms
+        hash = &zrtpHashes.getByName(mandatoryHash);
         return &zrtpPubKeys.getByName(mandatoryPubKey);
     }
-
-    // If we have only one algorithm in common or if the first entry matches - take it.
-    // Otherwise determine which algorithm from the intersection lists is first in the 
-    // list of ordered algorithms and select it (RFC6189, section 4.1.2).
     AlgorithmEnum* useAlgo;
-    if (numPeerIntersect > 1 && *(int32_t*)(ownIntersect[0]->getName()) != *(int32_t*)(peerIntersect[0]->getName())) {
+    if (numAlgosIntersect > 1 && *(int32_t*)(algosConf[0]->getName()) != *(int32_t*)(algosIntersect[0]->getName())) {
         int own, peer;
 
-        const int32_t *name = (int32_t*)ownIntersect[0]->getName();
+        const int32_t *name = (int32_t*)algosConf[0]->getName();
         for (own = 0; own < numOrderedAlgos; own++) {
             if (*name == *(int32_t*)orderedAlgos[own])
                 break;
         }
-        name = (int32_t*)peerIntersect[0]->getName();
+        name = (int32_t*)algosIntersect[0]->getName();
         for (peer = 0; peer < numOrderedAlgos; peer++) {
             if (*name == *(int32_t*)orderedAlgos[peer])
                 break;
         }
         if (own < peer) {
-            useAlgo = ownIntersect[0];
+            useAlgo = algosConf[0];
         }
         else {
-            useAlgo = peerIntersect[0];
+            useAlgo = algosIntersect[0];
         }
         // find fastest of conf vs intersecting
     }
     else {
-        useAlgo = peerIntersect[0];
+        useAlgo = algosIntersect[0];
     }
-    int32_t algoName = *(int32_t*)(useAlgo->getName());
-
     // select a corresponding strong hash if necessary.
-    if (algoName == *(int32_t*)ec38 || algoName == *(int32_t*)e414) {
-        hash = getStrongHashOffered(hello, algoName);
-        cipher = getStrongCipherOffered(hello, algoName);
+    if (*(int32_t*)(useAlgo->getName()) == *(int32_t*)ec38) {
+        hash = getStrongHashOffered(hello);
+        cipher = getStrongCipherOffered(hello);
     }
     else {
-        hash = getHashOffered(hello, algoName);;
-        cipher = getCipherOffered(hello, algoName);
+        hash = findBestHash(hello);
     }
-    authLength = getAuthLenOffered(hello, algoName);
     return useAlgo;
 }
 
@@ -1541,14 +1450,14 @@
     if (num == 0) {
         return &zrtpSasTypes.getByName(mandatorySasType);
     }
-    // Build list of configured SAS algorithm names
+    // Buildlist 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++;
@@ -1606,109 +1515,27 @@
     return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
 }
 
-// The following set of functions implement a 'non-NIST first policy' if nonNist computes 
-// to true. They prefer nonNist algorithms if these are available. Otherwise they use the NIST
-// counterpart or simply call the according findBest*(...) function.
-//
-// Only the findBestPubkey(...) function calls them after it selected the public key algorithm.
-// If the public key algorithm is non-NIST and if the policy is set to PreferNonNist then
-// nonNist becomes true.
-//
-// The functions work according to the RFC6189 spec: the initiator can select every algorithm
-// that both parties support. Thus the Initiator can even select an algorithm the wasn't offered
-// in its own Hello packet but that the Initiator found in the peer's Hello and that is available
-// for it.
-//
-AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
+AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello) {
 
     int numHash = hello->getNumHashes();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < numHash; i++) {
-            int32_t nm = *(int32_t*)(hello->getHashType(i));
-            if (nm == *(int32_t*)skn3) {
-                return &zrtpHashes.getByName((const char*)hello->getHashType(i));
-            }
-        }
-    }
     for (int i = 0; i < numHash; i++) {
-        int32_t nm = *(int32_t*)(hello->getHashType(i));
-        if (nm == *(int32_t*)s384 || nm == *(int32_t*)skn3) {
+        if (*(int32_t*)(hello->getHashType(i)) == *(int32_t*)s384) {
             return &zrtpHashes.getByName((const char*)hello->getHashType(i));
         }
     }
-    return NULL;         // returning NULL -> prepareCommit(...) terminates ZRTP, missing strong hash is an error
+    return NULL;
 }
 
-AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
+AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello) {
 
     int num = hello->getNumCiphers();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getCipherType(i));
-            if (nm == *(int32_t*)two3) {
-                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
-            }
-        }
-    }
     for (int i = 0; i < num; i++) {
-        int32_t nm = *(int32_t*)(hello->getCipherType(i));
-        if (nm == *(int32_t*)aes3 || nm == *(int32_t*)two3) {
+        if (*(int32_t*)(hello->getCipherType(i)) == *(int32_t*)aes3 ||
+            *(int32_t*)(hello->getCipherType(i)) == *(int32_t*)two3) {
             return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
         }
     }
-    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumHashes();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getHashType(i));
-            if (nm == *(int32_t*)skn2 || nm == *(int32_t*)skn3) {
-                return &zrtpHashes.getByName((const char*)hello->getHashType(i));
-            }
-        }
-    }
-    return findBestHash(hello);
-}
-
-AlgorithmEnum* ZRtp::getCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumCiphers();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getCipherType(i));
-            if (nm == *(int32_t*)two2 || nm == *(int32_t*)two3) {
-                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
-            }
-        }
-    }
-    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumAuth();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getAuthLen(i));
-            if (nm == *(int32_t*)sk32 || nm == *(int32_t*)sk64) {
-                return &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
-            }
-        }
-    }
-    return findBestAuthLen(hello);
+    return NULL;
 }
 
 bool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {
@@ -1731,10 +1558,6 @@
 bool ZRtp::verifyH2(ZrtpPacketCommit *commit) {
     uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
 
-    // packet does not have the correct size, treat H2 verfication as failed.
-    if (!commit->isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange))
-        return false;
-
     sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);
     if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
         return false;
@@ -1770,7 +1593,6 @@
     uint8_t randBuf[RS_LENGTH];
     uint32_t macLen;
 
-    fprintf(stderr, "Compute shared secrets\n");
     detailInfo.secretsCached = 0;
     if (!zidRec->isRs1Valid()) {
         randomZRTP(randBuf, RS_LENGTH);
@@ -1796,6 +1618,15 @@
         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);
@@ -1807,28 +1638,6 @@
         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);
-        }
-    }
 }
 
 /*
@@ -1875,17 +1684,12 @@
         rsFound = 0x8;
         detailInfo.secretsMatched = Rs2;
     }
-
+    /* *** Not yet supported
     if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
-        DEBUGOUT((fprintf(stdout, "Initiator: Match for aux secret found\n")));
+    DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
         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])));
@@ -1900,7 +1704,6 @@
         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);
@@ -1977,7 +1780,7 @@
             data[pos] = (unsigned char*)&sLen[i];
             length[pos++] = sizeof(uint32_t);
             data[pos] = (unsigned char*)setD[i];
-            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+            length[pos++] = RS_LENGTH;
         }
         else {                           // no machting secret, set length 0, skip secret
             sLen[i] = 0;
@@ -2039,17 +1842,12 @@
         rsFound |= 0x8;
         detailInfo.secretsMatched = Rs2;
     }
-
-    if (memcmp(auxSecretIDi, dhPart->getAuxSecretId(), 8) == 0) {
-        DEBUGOUT((fprintf(stdout, "Responder: Match for aux secret found\n")));
-        setD[1] = auxSecret;
-        detailInfo.secretsMatched |= Aux;
-        detailInfo.secretsMatchedDH |= Aux;
+    /* ***** not yet supported
+    if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
+    DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", ownZidzid[0])));
+        setD[1] = ;
     }
-    // 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])));
@@ -2063,7 +1861,6 @@
         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);
@@ -2142,7 +1939,7 @@
             data[pos] = (unsigned char*)&sLen[i];
             length[pos++] = sizeof(uint32_t);
             data[pos] = (unsigned char*)setD[i];
-            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+            length[pos++] = RS_LENGTH;
         }
         else {                           // no machting secret, set length 0, skip secret
             sLen[i] = 0;
@@ -2392,34 +2189,6 @@
         hashCtxFunction = sha384Ctx;
         hashCtxListFunction = sha384Ctx;
         break;
-
-    case 2:
-        hashLength = SKEIN256_DIGEST_LENGTH;
-        hashFunction = skein256;
-        hashListFunction = skein256;
-
-        hmacFunction = macSkein256;
-        hmacListFunction = macSkein256;
-
-        createHashCtx = createSkein256Context;
-        closeHashCtx = closeSkein256Context;
-        hashCtxFunction = skein256Ctx;
-        hashCtxListFunction = skein256Ctx;
-        break;
-
-    case 3:
-        hashLength = SKEIN384_DIGEST_LENGTH;
-        hashFunction = skein384;
-        hashListFunction = skein384;
-
-        hmacFunction = macSkein384;
-        hmacListFunction = macSkein384;
-
-        createHashCtx = createSkein384Context;
-        closeHashCtx = closeSkein384Context;
-        hashCtxFunction = skein384Ctx;
-        hashCtxListFunction = skein384Ctx;
-        break;
     }
 }
 
@@ -2433,7 +2202,6 @@
         return;
 
     zidRec->setSasVerified();
-    saveZidRecord = true;
     getZidCacheInstance()->saveRecord(zidRec);
 }
 
@@ -2443,14 +2211,6 @@
     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) {
 
@@ -2502,32 +2262,33 @@
     }
 }
 
-void ZRtp::setClientId(std::string id, HelloPacketVersion* hpv) {
+void ZRtp::setClientId(std::string id) {
+    if (id.size() < CLIENT_ID_SIZE) {
+        unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
+        memcpy(tmp, id.c_str(), id.size());
+        tmp[CLIENT_ID_SIZE] = 0;
+        zrtpHello.setClientId(tmp);
+    } else {
+        zrtpHello.setClientId((unsigned char*)id.c_str());
+    }
 
-    unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
-    memcpy(tmp, id.c_str(), id.size() > CLIENT_ID_SIZE ? CLIENT_ID_SIZE : id.size());
-    tmp[CLIENT_ID_SIZE] = 0;
+    int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
 
-    hpv->packet->setClientId(tmp);
-
-    int32_t len = hpv->packet->getLength() * ZRTP_WORD_SIZE;
-
-    // Hello packets are ready now, compute its HMAC
+    // Hello packet is ready now, compute its HMAC
     // (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello
     // use the implicit hash function
     uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
     uint32_t macLen;
-    hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)hpv->packet->getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
-    hpv->packet->setHMAC(hmac);
+    hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
+    zrtpHello.setHMAC(hmac);
 
     // calculate hash over the final Hello packet, refer to chap 9.1 how to
     // use this hash in SIP/SDP.
-    hashFunctionImpl((uint8_t*)hpv->packet->getHeaderBase(), len, hpv->helloHash);
+    hashFunctionImpl((uint8_t*)zrtpHello.getHeaderBase(), len, helloHash);
 }
 
 void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
-    uint32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
-    length = (length > sizeof(tempMsgBuffer)) ? sizeof(tempMsgBuffer) : length;
+    int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
     memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
     memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
     lengthOfMsgData = length;
@@ -2543,18 +2304,12 @@
     return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
 }
 
-std::string ZRtp::getHelloHash(int32_t index) {
+std::string ZRtp::getHelloHash() {
     std::ostringstream stm;
 
-    if (index < 0 || index >= MAX_ZRTP_VERSIONS)
-        return std::string();
+    uint8_t* hp = helloHash;
 
-    uint8_t* hp = helloPackets[index].helloHash;
-
-    char version[5] = {'\0'};
-    strncpy(version, (const char*)helloPackets[index].packet->getVersion(), ZRTP_WORD_SIZE);
-
-    stm << version;
+    stm << zrtpVersion;
     stm << " ";
     stm.fill('0');
     stm << hex;
@@ -2671,8 +2426,7 @@
     Event_t ev;
 
     ev.type = ZrtpPacket;
-    ev.packet = (uint8_t*)zrtpConf2Ack.getHeaderBase();
-    ev.length = sizeof (Conf2AckPacket_t) + 12;  // 12 is fixed ZRTP (RTP) header size
+    ev.packet = (uint8_t*)&zrtpConf2Ack;
 
     if (stateEngine != NULL) {
         stateEngine->processEvent(&ev);
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp b/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
index 7f7c3dd..f8e0c65 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-2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
@@ -164,10 +164,10 @@
         zrtpContext->zrtpEngine->resetSASVerified();
 }
 
-char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index) {
+char* zrtp_getHelloHash(ZrtpContext* zrtpContext) {
     std::string ret;
     if (zrtpContext && zrtpContext->zrtpEngine)
-        ret = zrtpContext->zrtpEngine->getHelloHash(index);
+        ret = zrtpContext->zrtpEngine->getHelloHash();
     else
         return NULL;
 
@@ -324,13 +324,6 @@
     return 0;
 }
 
-int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext) {
-    return zrtpContext->zrtpEngine->getNumberSupportedVersions();
-}
-
-int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext) {
-    return zrtpContext->zrtpEngine->getCurrentProtocolVersion();
-}
 /*
  * The following methods wrap the ZRTP Configure functions
  */
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp b/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
index fed2c04..ca2dce6 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-2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp b/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
index f57e871..bb71269 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
@@ -1,24 +1,3 @@
-/*

-  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>

@@ -156,8 +135,6 @@
 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() {}

@@ -183,10 +160,6 @@
     insert(dh3k, 0, "DH-3072", NULL, NULL, None);

     insert(ec38, 0, "ECDH-384", NULL, NULL, None);

     insert(mult, 0, "Multi-stream", NULL, NULL, None);

-#ifdef SUPPORT_NON_NIST

-    insert(e255, 0, "Curve25519", NULL, NULL, None);

-    insert(e414, 0, "Curve3617", NULL, NULL, None);

-#endif

 }

 

 PubKeyEnum::~PubKeyEnum() {}

@@ -225,8 +198,7 @@
 /*

  * The public methods are mainly a facade to the private methods.

  */

-ZrtpConfigure::ZrtpConfigure(): enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false),

-selectionPolicy(Standard){}

+ZrtpConfigure::ZrtpConfigure() : enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false) {}

 

 ZrtpConfigure::~ZrtpConfigure() {}

 

diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
index 5a96f52..85f1484 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
index b582777..af4bb09 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
index 67a51ee..f35dc82 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
index 6f13cae..f558759 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -66,17 +66,6 @@
     return true;
 }
 
-bool ZrtpPacketConfirm::isSignatureLengthOk() {
-    int32_t actualLen = getLength();
-    int32_t expectedLen = 19;                  // Confirm packet fixed part is 19 ZRTP words
-    int32_t sigLen = getSignatureLength();
-
-    if (sigLen > 0) {                          // We have a signature
-        expectedLen += sigLen + 1;             // +1 for the signature length field
-    }
-    return (expectedLen == actualLen);
-}
-
 int32_t ZrtpPacketConfirm::getSignatureLength() {
     int32_t sl = confirmHeader->sigLength & 0xff;
     if (confirmHeader->filler[1] == 1) {                              // do we have a 9th bit
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
index 1a89e16..8c59233 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -59,12 +59,6 @@
     else if (*(int32_t*)pkt == *(int32_t*)ec38) {
         dhLength = 96;
     }
-    else if (*(int32_t*)pkt == *(int32_t*)e255) {
-        dhLength = 32;
-    }
-    else if (*(int32_t*)pkt == *(int32_t*)e414) {
-        dhLength = 104;
-    }
     else
         return;
 
@@ -80,24 +74,18 @@
 
     int16_t len = getLength();
     DEBUGOUT((fprintf(stdout, "DHPart length: %d\n", len)));
-    if (len == 85) {         // Dh2k
+    if (len == 85) {
         dhLength = 256;
     }
-    else if (len == 117) {   // Dh3k
+    else if (len == 117) {
         dhLength = 384;
     }
-    else if (len == 37) {    // EC256
+    else if (len == 37) {
         dhLength = 64;
     }
-    else if (len == 45) {    // EC384
+    else if (len == 45) {
         dhLength = 96;
     }
-    else if (len == 29) {    // E255
-        dhLength = 32;
-    }
-    else if (len == 47) {    // E414
-        dhLength = 104;
-    }
     else {
         pv = NULL;
         return;
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
index 94d4dc1..a9d881e 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
index d0d0f33..3a30977 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
index bc885ef..6635fa3 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2012 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -19,7 +19,6 @@
  * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 
-#include <ctype.h>
 #include <libzrtpcpp/ZrtpPacketHello.h>
 
 
@@ -63,6 +62,8 @@
     setLength(length / ZRTP_WORD_SIZE);
     setMessageType((uint8_t*)HelloMsg);
 
+    setVersion((uint8_t*)zrtpVersion);
+
     uint32_t lenField = nHash << 16;
     for (int32_t i = 0; i < nHash; i++) {
         AlgorithmEnum& hash = config->getAlgoAt(HashAlgorithm, i);
@@ -101,25 +102,14 @@
     zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)data)->hdr;	// the standard header
     helloHeader = (Hello_t *)&((HelloPacket_t *)data)->hello;
 
-    // Force the isLengthOk() check to fail when we process the packet.
-    if (getLength() < HELLO_FIXED_PART_LEN) {
-        computedLength = 0;
-        return;
-    }
-
     uint32_t t = *((uint32_t*)&helloHeader->flags);
     uint32_t temp = zrtpNtohl(t);
 
     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;
@@ -135,14 +125,3 @@
 ZrtpPacketHello::~ZrtpPacketHello() {
     DEBUGOUT((fprintf(stdout, "Deleting Hello packet: alloc: %x\n", allocated)));
 }
-
-int32_t ZrtpPacketHello::getVersionInt() {
-    uint8_t* vp = getVersion();
-    int32_t version = 0;
-
-    if (isdigit(*vp) && isdigit(*vp+2)) {
-        version = (*vp - '0') * 10;
-        version += *(vp+2) - '0';
-    }
-    return version;
-}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
index 2849f2d..2d752b7 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
index b79e4ac..9a1f90f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -30,7 +30,7 @@
     setZrtpId();
     setLength((sizeof(PingPacket_t) / ZRTP_WORD_SIZE) - 1);
     setMessageType((uint8_t*)PingMsg);
-    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification
+    setVersion((uint8_t*)zrtpVersion);
 }
 
 ZrtpPacketPing::ZrtpPacketPing(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
index 0bee991..2331640 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -30,7 +30,7 @@
     setZrtpId();
     setLength((sizeof(PingAckPacket_t) / ZRTP_WORD_SIZE) - 1);
     setMessageType((uint8_t*)PingAckMsg);
-    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification
+    setVersion((uint8_t*)zrtpVersion);
 }
 
 ZrtpPacketPingAck::ZrtpPacketPingAck(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
index a531e2f..6ff0c7a 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-20013 Werner Dittmann
+  Copyright (C) 2006-20011 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp b/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
index c8b7f54..d132e28 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp b/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
new file mode 100644
index 0000000..9e838da
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
@@ -0,0 +1,843 @@
+/*
+  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/zrtp/ZrtpSdesStream.cpp b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
index a6756af..a987032 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
@@ -1,28 +1,7 @@
-/*
-  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>
@@ -32,16 +11,17 @@
 #include <srtp/CryptoContext.h>
 #include <srtp/CryptoContextCtrl.h>
 #include <cryptcommon/ZrtpRandom.h>
-#include <crypto/hmac384.h>
-
 
 #if defined(_WIN32) || defined(_WIN64)
 # define snprintf _snprintf
 #endif
 
-// SRTP authentication tag length is 80 bits = 10 bytes
-#define ZRTP_TUNNEL_AUTH_LEN  10
-#define ZRTP_TUNNEL_LABEL     10
+/*
+ * These functions support 256 bit encryption algorithms.
+ */
+#define MAX_KEY_LEN           32
+#define MAX_SALT_LEN          14
+
 /*
  * The ABNF grammar for the crypto attribute is defined below (from RFC 4568):
  *
@@ -105,19 +85,6 @@
 
 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;
@@ -134,18 +101,17 @@
 /* NOTE: the b64len of a 128 bit suite is 40, a 256bit suite uses 64 characters */
 static suiteParam knownSuites[] = {
     {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_32, "AES_CM_128_HMAC_SHA1_32", 128, 112, 160,
-     hs32, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
+     hs32, aes1, 40, (uint64_t)1<<48, 1<<31
     },
     {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_80, "AES_CM_128_HMAC_SHA1_80", 128, 112, 160,
-     hs80, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
+     hs80, aes1, 40, (uint64_t)1<<48, 1<<31
     },
     {(ZrtpSdesStream::sdesSuites)0, NULL, 0, 0, 0, 0, 0, 0, 0, 0}
 };
 
 ZrtpSdesStream::ZrtpSdesStream(const sdesSuites s) :
     state(STREAM_INITALIZED), suite(s), recvSrtp(NULL), recvSrtcp(NULL), sendSrtp(NULL),
-    sendSrtcp(NULL), srtcpIndex(0), recvZrtpTunnel(0), sendZrtpTunnel(0), cryptoMixHashLength(0), 
-    cryptoMixHashType(MIX_NONE)  {
+    sendSrtcp(NULL), srtcpIndex(0) {
 }
 
 ZrtpSdesStream::~ZrtpSdesStream() {
@@ -164,12 +130,6 @@
 
     delete recvSrtcp;
     recvSrtp = NULL;
-
-    delete recvZrtpTunnel;
-    recvZrtpTunnel = NULL;
-
-    delete sendZrtpTunnel;
-    sendZrtpTunnel = NULL;
 }
 
 bool ZrtpSdesStream::createSdes(char *cryptoString, size_t *maxLen, bool sipInvite) {
@@ -192,13 +152,13 @@
         state = OUT_PROFILE_READY;
     }
     else {
-        createSrtpContexts(sipInvite);
         state = SDES_SRTP_ACTIVE;
     }
     return s;
+
 }
 
-bool ZrtpSdesStream::parseSdes(const char *cryptoString, size_t length, bool sipInvite) {
+bool ZrtpSdesStream::parseSdes(char *cryptoString, size_t length, bool sipInvite) {
 
     if (sipInvite) {
         if (state != OUT_PROFILE_READY)
@@ -219,7 +179,6 @@
         // 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 {
@@ -258,36 +217,6 @@
     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)
@@ -306,70 +235,8 @@
     return knownSuites[suite].cipher;
 }
 
-const char* ZrtpSdesStream::getAuthAlgo() {
-    if (strcmp(knownSuites[suite].tagLength, hs80) == 0)
-        return "HMAC-SHA1 80 bit";
-    else
-        return "HMAC-SHA1 32 bit";
-}
-
-int ZrtpSdesStream::getCryptoMixAttribute(char *algoNames, size_t length) {
-
-    if (length < MIX_HMAC_STRING_MIN_LEN)
-        return 0;
-
-    // In case we support more than one MIX profile select the correct one if the
-    // application called setCryptoMixAttribute(...) and we already selected the one to use.
-    if (cryptoMixHashType != MIX_NONE) {
-        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
-            if (cp->hashLength == cryptoMixHashLength && cp->hashType == cryptoMixHashType) {
-                strcpy(algoNames, cp->name);
-                return strlen(cp->name);
-            }
-        }
-    }
-    // TODO: enhance here to support multiple algorithms (concatenate strings into the buffer until buffer full)
-    else {
-        strcpy(algoNames, knownMixAlgos[0].name);
-        return strlen(algoNames);
-    }
-    return 0;
-}
-
-bool ZrtpSdesStream::setCryptoMixAttribute(const char *algoNames) {
-
-    int len = strlen(algoNames);
-    if (len <= 0)
-        return false;
-
-    std::string algoIn(algoNames);
-    algoIn += ' ';
-
-    // split input name string and lookup if we support one of the offered algorithms
-    // We take the first match.
-    std::string delimiters = " ";
-    size_t current;
-    size_t next = -1;
-
-    do {
-        current = next + 1;
-        next = algoIn.find_first_of(delimiters, current);
-        if (next == std::string::npos)
-            break;
-
-        std::string tmps = algoIn.substr(current, next - current );
-        const char* nm = tmps.c_str();
-
-        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
-            if (strncmp(cp->name, nm, strlen(cp->name)) == 0) {
-                cryptoMixHashLength = cp->hashLength;
-                cryptoMixHashType = cp->hashType;
-                return true;
-            }
-        }
-    } while (true);
-
-    return false;
+const char* ZrtpSdesStream::getAuthAlgo(){
+    return knownSuites[suite].tagLength;
 }
 
 #ifdef WEAKRANDOM
@@ -417,213 +284,15 @@
     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;
 
-    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite parameters
+    /* Lookup crypto suite parameters */
+    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {
         if (knownSuites[sidx].suite == suite)
             break;
     }
@@ -631,29 +300,45 @@
         return false;
     }
     suiteParam *pSuite = &knownSuites[sidx];
-    _random(localKeySalt, sizeof(localKeySalt));
+    _random(keySalt, sizeof(keySalt));
 
     AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
-    localAuthn = SrtpAuthenticationSha1Hmac;
-    localAuthKeyLen = pSuite->authKeyLength / 8;
-    localTagLength = auth.getKeylen() / 8;
+    int authn = SrtpAuthenticationSha1Hmac;
+    int authKeyLen = pSuite->authKeyLength / 8;
+    int tagLength = auth.getKeylen() / 8;
 
     // If SDES will support other encryption algos - get it here based on
     // the algorithm name in suite
-    localCipher = SrtpEncryptionAESCM;
+    int cipher = SrtpEncryptionAESCM;
 
-    localKeyLenBytes = pSuite->keyLength / 8;
-    localSaltLenBytes = pSuite->saltLength / 8;
+    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);
 
     if (tag == -1)
         tag = 1;
 
-    // Get B64 code for master key and master salt and then construct the SDES crypto string
-    b64Len = b64Encode(localKeySalt, localKeyLenBytes + localSaltLenBytes, b64keySalt, sizeof(b64keySalt));
+    /* Get B64 code for master key and master salt */
+    b64Len = b64Encode(keySalt, keyLenBytes + saltLenBytes, 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;
 }
 
@@ -661,6 +346,7 @@
     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'};
@@ -676,22 +362,28 @@
         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;
     }
-    memcpy(cryptoString, cryptoStr, length);   // make own copy, null terminated
+    /* make own copy, null terminated */
+    memcpy(cryptoString, cryptoStr, length);
 
     *outTag = -1;
     elements = sscanf(cryptoString, parseCrypto, outTag, suiteName, keyParams, &charsScanned);
 
-    if (elements < minElementsCrypto) {        // Do we have enough elements in the string
+    /* 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);
         return false;
     }
 
-    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite
+    /* Lookup crypto suite */
+    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {
         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];
@@ -700,30 +392,57 @@
     /* Now scan the key parameters */
     elements = sscanf(keyParams, parseKeyParam, keySaltB64, lifetime, mkiVal, &mkiLength);
 
-    if (elements != minElementsKeyParam) {     // Currently we only accept key||salt B64 string, no other parameters 
+    /* 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);
         return false;
     }
 
-    remoteKeyLenBytes = pSuite->keyLength / 8;
-    remoteSaltLenBytes = pSuite->saltLength / 8;
+    int keyLenBytes = pSuite->keyLength / 8;
+    int saltLenBytes = pSuite->saltLength / 8;
 
-    if (strlen(keySaltB64) != pSuite->b64length) {  // Check if key||salt B64 string hast the correct length
+    /* 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);
         return false;
     }
-    i = b64Decode(keySaltB64, pSuite->b64length, remoteKeySalt, remoteKeyLenBytes + remoteSaltLenBytes);
 
-    if (i != (remoteKeyLenBytes + remoteSaltLenBytes)) {  // Did the B64 decode delivered enough data for key||salt
+    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);
         return false;
     }
 
     AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
-    remoteAuthn = SrtpAuthenticationSha1Hmac;
-    remoteAuthKeyLen = pSuite->authKeyLength / 8;
-    remoteTagLength = auth.getKeylen() / 8;
+    int authn = SrtpAuthenticationSha1Hmac;
+    int authKeyLen = pSuite->authKeyLength / 8;
+    int tagLength = auth.getKeylen() / 8;
 
     // If SDES will support other encryption algos - get it here based on
     // the algorithm name in suite
-    remoteCipher = SrtpEncryptionAESCM;
+    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));
 
     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 11600a9..74dfb04 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2008 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -46,9 +46,14 @@
 };
 
 
-ZrtpStateClass::ZrtpStateClass(ZRtp *p) : parent(p), commitPkt(NULL), multiStream(false), secSubstate(Normal), sentVersion(0) {
+ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
+    parent = p;
+    secSubstate = Normal;
     engine = new ZrtpStates(states, numberOfStates, Initial);
 
+    commitPkt = NULL;
+    multiStream = false;
+
     // Set up timers according to ZRTP spec
     T1.start = 50;
     T1.maxResend = 20;
@@ -94,7 +99,7 @@
         if (!inState(WaitErrorAck)) {
             uint16_t totalLength = *(uint16_t*)(pkt+2);
             totalLength = zrtpNtohs(totalLength) * ZRTP_WORD_SIZE;
-            totalLength += 12 + sizeof(uint32_t);           // 12 bytes is fixed header, uint32_t is CRC
+            totalLength += 12 + sizeof(uint32_t);           // !2 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);
@@ -123,9 +128,7 @@
         else if (first == 'p' && middle == ' ' && last == ' ') {
             ZrtpPacketPing ppkt(pkt);
             ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);
-            if (ppktAck != NULL) {          // ACK only to valid PING packet, otherwise ignore it
-                parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
-            }
+            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
             parent->synchLeave();
             return;
         }
@@ -154,11 +157,10 @@
     DEBUGOUT((cout << "Checking for match in Initial.\n"));
 
     if (event->type == ZrtpInitial) {
-        ZrtpPacketHello* hello = parent->prepareHello();
-        sentVersion = hello->getVersionInt();
+	ZrtpPacketHello* hello = parent->prepareHello();
 
-        // remember packet for easy resend in case timer triggers
-        sentPacket = static_cast<ZrtpPacketBase *>(hello);
+	// remember packet for easy resend in case timer triggers
+	sentPacket = static_cast<ZrtpPacketBase *>(hello);
 
         if (!parent->sendPacketZRTP(sentPacket)) {
             sendFailed();                 // returns to state Initial
@@ -168,7 +170,7 @@
             timerFailed(SevereNoTimer);      // returns to state Initial
             return;
         }
-        nextState(Detect);
+	nextState(Detect);
     }
 }
 
@@ -236,8 +238,6 @@
          * - our peer acknowledged our Hello packet, we have not seen the peer's Hello yet
          * - cancel timer T1 to stop resending Hello
          * - switch to state AckDetected, wait for peer's Hello (F3)
-         * 
-         * When we receive an HelloAck this also means that out partner accepted our protocol version.
          */
         if (first == 'h' && last =='k') {
             cancelTimer();
@@ -247,8 +247,7 @@
         }
         /*
          * Hello:
-         * - send HelloAck packet to acknowledge the received Hello packet if versions match.
-         *   Otherweise negotiate ZRTP versions.
+         * - send HelloAck packet to acknowledge the received Hello packet 
          * - use received Hello packet to prepare own Commit packet. We need to
          *   do it at this point because we need the hash value computed from
          *   peer's Hello packet. Follwing states my use the prepared Commit.
@@ -257,58 +256,7 @@
          * - Don't clear sentPacket, points to Hello
          */
         if (first == 'h' && last ==' ') {
-            ZrtpPacketHello hpkt(pkt);
-
             cancelTimer();
-
-            /*
-             * Check and negotiate the ZRTP protocol version first.
-             *
-             * This selection mechanism relies on the fact that we sent the highest supported protocol version in
-             * the initial Hello packet with as stated in RFC6189, section 4.1.1
-             */
-            int32_t recvVersion = hpkt.getVersionInt();
-            if (recvVersion > sentVersion) {   // We don't support this version, stay in state with timer active
-                if (startTimer(&T1) <= 0) {
-                    timerFailed(SevereNoTimer);      // returns to state Initial
-                }
-                return;
-            }
-
-            /*
-             * The versions don't match. Start negotiating versions. This negotiation stays in the Detect state.
-             * Only if the received version matches our own sent version we start to send a HelloAck.
-             */
-            if (recvVersion != sentVersion) {
-                ZRtp::HelloPacketVersion* hpv = parent->helloPackets;
-
-                int32_t index;
-                for (index = 0; hpv->packet && hpv->packet != parent->currentHelloPacket; hpv++, index++)   // Find current sent Hello
-                    ;
-
-                for(; index >= 0 && hpv->version > recvVersion; hpv--, index--)   // find a supported version less-equal to received version
-                    ;
-
-                if (index < 0) {
-                    sendErrorPacket(UnsuppZRTPVersion);
-                    return;
-                }
-                parent->currentHelloPacket = hpv->packet;
-                sentVersion = parent->currentHelloPacket->getVersionInt();
-
-                // remember packet for easy resend in case timer triggers
-                sentPacket = static_cast<ZrtpPacketBase *>(parent->currentHelloPacket);
-
-                if (!parent->sendPacketZRTP(sentPacket)) {
-                    sendFailed();                 // returns to state Initial
-                    return;
-                }
-                if (startTimer(&T1) <= 0) {
-                    timerFailed(SevereNoTimer);      // returns to state Initial
-                    return;
-                }
-                return;
-            }
             ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();
 
             if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
@@ -317,6 +265,7 @@
             }
             // Use peer's Hello packet to create my commit packet, store it 
             // for possible later usage in state AckSent
+            ZrtpPacketHello hpkt(pkt);
             commitPkt = parent->prepareCommit(&hpkt, &errorCode);
 
             nextState(AckSent);
@@ -343,7 +292,7 @@
             nextState(Detect);
         }
     }
-    // If application calls zrtpStart() to restart discovery
+    // If application call zrtpStart() to restart discovery
     else if (event->type == ZrtpInitial) {
         cancelTimer();
         if (!parent->sendPacketZRTP(sentPacket)) {
@@ -411,36 +360,36 @@
      */
     if (event->type == ZrtpPacket) {
         pkt = event->packet;
-        msg = (char *)pkt + 4;
+	msg = (char *)pkt + 4;
 
-        first = tolower(*msg);
-        last = tolower(*(msg+7));
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
 
-        /*
+	/*
          * HelloAck:
          * The peer answers with HelloAck to own HelloAck/Hello. Send Commit
          * and try Initiator mode. The requirement defined in chapter 4.1 to
          * have a complete Hello/HelloAck is fulfilled.
-         * - stop Hello timer T1
-         * - send own Commit message
-         * - switch state to CommitSent, start Commit timer, assume Initiator
-         */
-        if (first == 'h' && last =='k') {
-            cancelTimer();
+	 * - stop Hello timer T1
+	 * - send own Commit message
+	 * - switch state to CommitSent, start Commit timer, assume Initiator
+	 */
+	if (first == 'h' && last =='k') {
+	    cancelTimer();
 
             // remember packet for easy resend in case timer triggers
             // Timer trigger received in new state CommitSend
             sentPacket = static_cast<ZrtpPacketBase *>(commitPkt);
             commitPkt = NULL;                    // now stored in sentPacket
-            nextState(CommitSent);
+	    nextState(CommitSent);
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();             // returns to state Initial
                 return;
             }
             if (startTimer(&T2) <= 0) {
                 timerFailed(SevereNoTimer);  // returns to state Initial
-            }
-            return;
+	    }
+	    return;
         }
         /*
          * Hello:
@@ -472,7 +421,7 @@
          * - switch to state WaitDHPart2 and wait for peer's DHPart2
          * - don't start timer, we are responder
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             cancelTimer();
             ZrtpPacketCommit cpkt(pkt);
 
@@ -510,7 +459,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
@@ -612,7 +561,7 @@
          * - Initiator role, thus start timer T2 to monitor timeout for Commit
          */
 
-        if (first == 'h' && last == ' ') {
+        if (first == 'h') {
             // Parse peer's packet data into a Hello packet
             ZrtpPacketHello hpkt(pkt);
             ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
@@ -662,7 +611,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
 
-    char *msg, first, last;
+    char *msg, first;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -671,13 +620,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
         /*
          * Hello:
          * - resend HelloAck
          * - stay in WaitCommit
          */
-        if (first == 'h' && last == ' ') {
+        if (first == 'h') {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();       // returns to state Initial
             }
@@ -690,7 +638,7 @@
          * - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode
          * - don't start timer, we are responder
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             ZrtpPacketCommit cpkt(pkt);
 
             if (!multiStream) {
@@ -758,7 +706,7 @@
 
     DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
 
-    char *msg, first, middle, last, secondLast;
+    char *msg, first, last;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -767,9 +715,7 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        middle = tolower(*(msg+4));
         last = tolower(*(msg+7));
-        secondLast = tolower(*(msg+6));
 
         /*
          * HelloAck or Hello:
@@ -777,7 +723,7 @@
          *   ignore it
          * - no switch in state, leave timer as it is
          */
-        if (first == 'h' && middle == 'o' && (last =='k' || last == ' ')) {
+        if (first == 'h' && (last =='k' || last == ' ')) {
             return;
         }
 
@@ -802,11 +748,6 @@
             }
             cancelTimer();         // this cancels the Commit timer T2
 
-            if (!zpCo.isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange)) {
-                sendErrorPacket(CriticalSWError);
-                return;
-            }
-
             // if our hvi is less than peer's hvi: switch to Responder mode and
             // send DHPart1 or Confirm1 packet. Peer (as Initiator) will retrigger if
             // necessary
@@ -859,7 +800,7 @@
          * - switch to WaitConfirm1
          * - start timer to resend DHPart2 if necessary, we are Initiator
          */
-        if (first == 'd' && secondLast == '1') {
+        if (first == 'd') {
             cancelTimer();
             sentPacket = NULL;
             ZrtpPacketDHPart dpkt(pkt);
@@ -891,11 +832,6 @@
             return;
         }
 
-        /*
-         * Confirm1 and multi-stream mode
-         * - switch off resending commit
-         * - prepare Confirm2
-         */
         if (multiStream && (first == 'c' && last == '1')) {
             cancelTimer();
             ZrtpPacketConfirm cpkt(pkt);
@@ -966,7 +902,7 @@
 
     DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
 
-    char *msg, first, secondLast, last;
+    char *msg, first;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -975,14 +911,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
-        secondLast = tolower(*(msg+6));
         /*
          * Commit:
          * - resend DHPart1
          * - stay in state
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 return sendFailed();       // returns to state Initial
             }
@@ -994,7 +928,7 @@
          * - switch to WaitConfirm2
          * - No timer, we are responder
          */
-        if (first == 'd' && secondLast == '2') {
+        if (first == 'd') {
             ZrtpPacketDHPart dpkt(pkt);
             ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);
 
@@ -1135,7 +1069,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
 
-    char *msg, first, secondLast, last;
+    char *msg, first, last;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -1144,7 +1078,6 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        secondLast = tolower(*(msg+6));
         last = tolower(*(msg+7));
 
         /*
@@ -1152,7 +1085,7 @@
          * - resend Confirm1 packet
          * - stay in state
          */
-        if ((first == 'd' && secondLast == '2') || (multiStream && (first == 'c' && last == ' '))) {
+        if (first == 'd' || (multiStream && (first == 'c' && last == ' '))) {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();             // returns to state Initial
             }
@@ -1218,7 +1151,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
 
-    char *msg, first, last;
+    char *msg, first;
     uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
@@ -1226,13 +1159,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
          /*
          * ConfAck:
          * - Switch off resending Confirm2
          * - switch to SecureState
          */
-        if (first == 'c' && last == 'k') {
+        if (first == 'c') {
             cancelTimer();
             sentPacket = NULL;
             // Receiver was already enabled after sending Confirm2 packet
@@ -1276,45 +1208,44 @@
 void ZrtpStateClass::evWaitClearAck(void) {
     DEBUGOUT((cout << "Checking for match in ClearAck.\n"));
 
-//     char *msg, first, last, middle;
-//     uint8_t *pkt;
-// 
-//     if (event->type == ZrtpPacket) {
-// 	pkt = event->packet;
-// 	msg = (char *)pkt + 4;
-// 
-// 	first = tolower(*msg);
-//     middle = tolower(*(msg+4));
-// 	last = tolower(*(msg+7));
-// 
-// 	/*
-// 	 * ClearAck:
-// 	 * - stop resending GoClear,
-// 	 * - switch to state AckDetected, wait for peer's Hello
-// 	 */
-// 	if (first == 'c' && middle == 'r' && last =='k') {
-// 	    cancelTimer();
-// 	    sentPacket = NULL;
-// 	    nextState(Initial);
-// 	}
-//     }
-//     // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
-//     else if (event->type == Timer) {
-//         if (!parent->sendPacketZRTP(sentPacket)) {
-//             sendFailed();                 // returns to state Initial
-//             return;
-//         }
-//         if (nextTimer(&T2) <= 0) {
-//             timerFailed(SevereTooMuchRetries);     // returns to state Initial
-//         }
-//     }
-//     else {  // unknown Event type for this state (covers Error and ZrtpClose)
-//         if (event->type != ZrtpClose) {
-//             parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
-//         }
-// 	sentPacket = NULL;
-// 	nextState(Initial);
-//     }
+    char *msg, first, last;
+    uint8_t *pkt;
+
+    if (event->type == ZrtpPacket) {
+	pkt = event->packet;
+	msg = (char *)pkt + 4;
+
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
+
+	/*
+	 * ClearAck:
+	 * - stop resending GoClear,
+	 * - switch to state AckDetected, wait for peer's Hello
+	 */
+	if (first == 'c' && last =='k') {
+	    cancelTimer();
+	    sentPacket = NULL;
+	    nextState(Initial);
+	}
+    }
+    // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);     // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+	sentPacket = NULL;
+	nextState(Initial);
+    }
 }
 
 
@@ -1418,7 +1349,7 @@
         }
         /*
          * GoClear received, handle it. TODO fix go clear handling
-         *
+         */
         if (first == 'g' && last == 'r') {
             ZrtpPacketGoClear gpkt(pkt);
             ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);
@@ -1428,18 +1359,12 @@
             }
         // TODO Timeout to resend clear ack until user user confirmation
         }
-        */
     }
     else if (event->type == Timer) {
         // Ignore stray timeout in this state
         ;
     }
-    // unknown Event type for this state (covers Error and ZrtpClose)
-    else  {
-        // If in secure state ingnore error events to avoid Error packet injection
-        // attack - found by Dmitry Monakhov (dmonakhov@openvz.org)
-        if (event->type == ErrorPkt)
-            return;
+    else  {  // unknown Event type for this state (covers Error and ZrtpClose)
         sentPacket = NULL;
         parent->srtpSecretsOff(ForSender);
         parent->srtpSecretsOff(ForReceiver);
diff --git a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
index 14ba61f..93e2ccf 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
+++ b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2008 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -22,9 +22,8 @@
 #include <libzrtpcpp/ZrtpConfigure.h>
 //                             1
 //                    1234567890123456
-char clientId[] =    "GNU ZRTP 4.0.0  "; // 16 chars max.
-char zrtpVersion_11[] = "1.10";          // must be 4 chars
-char zrtpVersion_12[] = "1.20";          // must be 4 chars
+char clientId[] =    "GNU ZRTP 3.0.0  "; // 16 chars max.
+char zrtpVersion[] = "1.10";             // must be 4 chars
 /**
  *
  */
@@ -70,8 +69,6 @@
 
 char s256[] = "S256";
 char s384[] = "S384";
-char skn2[] = "SKN2";
-char skn3[] = "SKN3";
 const char* mandatoryHash = s256;
 
 char aes3[] = "AES3";
@@ -86,8 +83,6 @@
 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 f3042f8..43a3306 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2012-2013 by Werner Dittmann
+  Copyright (C) 2012 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,7 +29,8 @@
  * 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 7223bdf..b121893 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
+++ b/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
index 1c743d2..cb17b8f 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-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
index 066035f..19acb6e 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-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
index bc8897a..0b6e213 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, 2013 Werner Dittmann
+  Copyright (C) 2006, 2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
index a0ecc65..a53a674 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-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
index b20bfe6..1015c44 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-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp b/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
index c26a23c..c7d7c57 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-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
index 1e3ceb7..955c40b 100644
--- a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
+++ b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2012-2013 Werner Dittmann
+  Copyright (C) 2012 Werner Dittmann
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -124,7 +124,7 @@
     hmacSha256Init(&ctx, key, keyLength);
     hmacSha256Update(&ctx, data, dataLength);
     hmacSha256Final(&ctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
+    *macLength = SHA256_BLOCK_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_DIGEST_SIZE;
+    *macLength = SHA256_BLOCK_SIZE;
 }
 
 void* createSha256HmacContext(uint8_t* key, int32_t keyLength)
@@ -159,7 +159,7 @@
     hmacSha256Reset(pctx);
     hmacSha256Update(pctx, data, dataLength);
     hmacSha256Final(pctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
+    *macLength = SHA256_BLOCK_SIZE;
 }
 
 void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
@@ -174,7 +174,7 @@
         dataLength++;
     }
     hmacSha256Final(pctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
+    *macLength = SHA256_BLOCK_SIZE;
 }
 
 void freeSha256HmacContext(void* ctx)
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
index c7a7abd..40b4487 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_DIGEST_SIZE;
+    *macLength = SHA384_BLOCK_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_DIGEST_SIZE;
+    *macLength = SHA384_BLOCK_SIZE;
 }
 
 void* createSha384HmacContext(uint8_t* key, int32_t keyLength)
@@ -159,7 +159,7 @@
     hmacSha384Reset(pctx);
     hmacSha384Update(pctx, data, dataLength);
     hmacSha384Final(pctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
+    *macLength = SHA384_BLOCK_SIZE;
 }
 
 void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
@@ -174,7 +174,7 @@
         dataLength++;
     }
     hmacSha384Final(pctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
+    *macLength = SHA384_BLOCK_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 2c5c8de..17961c3 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-2013 Werner Dittmann
+  Copyright (C) 2006 Werner Dittmann
 
   This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.
 
@@ -18,16 +18,19 @@
 
 #include <stdio.h>
 #include <openssl/evp.h>
-#include <config.h>
+#include <libzrtpcpp-config.h>
 
-#ifdef _MSWINDOWS_
+#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
+#undef  _MSWINDOWS_
+#define _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
 
@@ -71,6 +74,7 @@
 }
 
 #ifdef _MSWINDOWS_
+#define __LOCKING
 
 static HANDLE *lock_cs;
 
@@ -108,7 +112,8 @@
 #endif /* OPENSSL_SYS_WIN32 */
 
 
-#if defined SOLARIS && !defined HAVE_PTHREAD_H
+#if defined SOLARIS && !defined HAVE_PTHREAD_H && !defined(_MSWINDOWS)
+#define __LOCKING
 
 static mutex_t *lock_cs;
 static long *lock_count;
@@ -175,6 +180,7 @@
 #endif /* SOLARIS */
 
 
+#ifndef __LOCKING
 static pthread_mutex_t* lock_cs;
 static long* lock_count;
 
@@ -233,4 +239,4 @@
     return(ret);
 }
 */
-
+#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.c b/jni/libzrtp/sources/zrtp/crypto/sha2.c
index 22761f3..fccd1d2 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.c
+++ b/jni/libzrtp/sources/zrtp/crypto/sha2.c
@@ -754,7 +754,7 @@
     }
 }
 
-INT_RETURN sha2_all(unsigned char hval[], unsigned long size,
+INT_RETURN sha2(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 1ad3889..91d0745 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_all(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
+INT_RETURN  sha2(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 36127b9..959a620 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.h
+++ b/jni/libzrtp/sources/zrtp/crypto/sha256.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.h b/jni/libzrtp/sources/zrtp/crypto/sha384.h
index d4ccce5..6cb7a70 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.h
+++ b/jni/libzrtp/sources/zrtp/crypto/sha384.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp b/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
deleted file mode 100644
index 94cff63..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein256.h>
-
-#include <stdlib.h>
-
-void skein256(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
-    skeinUpdate(&ctx, data, dataLength);
-
-    skeinFinal(&ctx, digest);
-}
-
-void skein256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
-    while(*dataChunks) {
-        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    skeinFinal(&ctx, digest);
-}
-
-void* createSkein256Context()
-{
-    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
-    skeinCtxPrepare(ctx, SKEIN_SIZE);
-    skeinInit(ctx, SKEIN256_DIGEST_LENGTH*8);
-    return (void*)ctx;
-}
-
-void closeSkein256Context(void* ctx, unsigned char* digest)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    if (digest != NULL) {
-        skeinFinal(hd, digest);
-    }
-    free(hd);
-}
-
-void skein256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    skeinUpdate(hd, data, dataLength);
-}
-
-void skein256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    while (*dataChunks) {
-        skeinUpdate(hd, *dataChunks, *dataChunkLength);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.h b/jni/libzrtp/sources/zrtp/crypto/skein256.h
deleted file mode 100644
index 6d4e722..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein256 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN256_H
-#define _SKEIN256_H
-
-/**
- * @file skein256.h
- * @brief Functions that provide Skein256 support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH  32
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein256 digest.
- *
- * This functions takes one data chunk and computes its Skein256 digest. This 
- * function creates and deletes an own Skein256 context to perform the Skein256
- * operations.
- *
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data,
-            unsigned int data_length,
-            unsigned char *digest);
-
-/**
- * Compute Skein256 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein256 digest.
- * This function creates and deletes an own Skein256 context to perform the
- * Skein256 operations.
- *
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data[],
-            unsigned int data_length[],
-            unsigned char *digest);
-/**
- * Create and initialize a Skein256 context.
- *
- * An application uses this context to hash several data into one Skein256
- * digest. See also skein256Ctx(...) and closeSha256Context(...).
- *
- * @return Returns a pointer to the initialized Skein256 context
- */
-void* createSkein256Context();
-
-/**
- * Compute a digest and close the SHa256 digest.
- *
- * An application uses this function to compute the Skein256 digest and to
- * close the Skein256 context.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param digest
- *    If this pointer is not NULL then it must point to a byte array that
- *    is big enough to hold the Skein256 digest (256 bit = 32 Bytes). If this
- *    pointer is NULL then the functions does not compute the digest but
- *    closes the context only. The context cannot be used anymore.
- */
-void closeSkein256Context(void* ctx,
-                        unsigned char* digest);
-
-/**
- * Update the Skein256 context with data.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param data
- *    Points to the data to update the context.
- * @param dataLength
- *    The length of the data in bytes.
- */
-void skein256Ctx(void* ctx, unsigned char* data, 
-               unsigned int dataLength);
-
-/**
- * Update the Skein256 context with several data chunks.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param dataChunks
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- *    Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein256Ctx(void* ctx, unsigned char* dataChunks[],
-               unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp b/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
deleted file mode 100644
index 1dbe608..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein384.h>
-
-#include <stdlib.h>
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH  48
-
-void skein384(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
-    skeinUpdate(&ctx, data, dataLength);
-
-    skeinFinal(&ctx, digest);
-}
-
-void skein384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
-    while(*dataChunks) {
-        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    skeinFinal(&ctx, digest);
-}
-
-void* createSkein384Context()
-{
-    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
-    skeinCtxPrepare(ctx, SKEIN_SIZE);
-    skeinInit(ctx, SKEIN384_DIGEST_LENGTH*8);
-    return (void*)ctx;
-}
-
-void closeSkein384Context(void* ctx, unsigned char* digest)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    if (digest != NULL) {
-        skeinFinal(hd, digest);
-    }
-    free(hd);
-}
-
-void skein384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    skeinUpdate(hd, data, dataLength);
-}
-
-void skein384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    while (*dataChunks) {
-        skeinUpdate(hd, *dataChunks, *dataChunkLength);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.h b/jni/libzrtp/sources/zrtp/crypto/skein384.h
deleted file mode 100644
index 61fd64e..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein384 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN384_H
-#define _SKEIN384_H
-
-/**
- * @file skein384.h
- * @brief Functions that provide Skein384 support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH  48
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein384 digest.
- *
- * This functions takes one data chunk and computes its Skein384 digest. This 
- * function creates and deletes an own Skein384 context to perform the Skein384
- * operations.
- *
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data,
-            unsigned int data_length,
-            unsigned char *digest);
-
-/**
- * Compute Skein384 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein384 digest.
- * This function creates and deletes an own Skein384 context to perform the
- * Skein384 operations.
- *
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data[],
-            unsigned int data_length[],
-            unsigned char *digest);
-/**
- * Create and initialize a Skein384 context.
- *
- * An application uses this context to hash several data into one Skein384
- * digest. See also skein384Ctx(...) and closeSha384Context(...).
- *
- * @return Returns a pointer to the initialized Skein384 context
- */
-void* createSkein384Context();
-
-/**
- * Compute a digest and close the SHa384 digest.
- *
- * An application uses this function to compute the Skein384 digest and to
- * close the Skein384 context.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param digest
- *    If this pointer is not NULL then it must point to a byte array that
- *    is big enough to hold the Skein384 digest (384 bit = 48 Bytes). If this
- *    pointer is NULL then the functions does not compute the digest but
- *    closes the context only. The context cannot be used anymore.
- */
-void closeSkein384Context(void* ctx,
-                        unsigned char* digest);
-
-/**
- * Update the Skein384 context with data.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param data
- *    Points to the data to update the context.
- * @param dataLength
- *    The length of the data in bytes.
- */
-void skein384Ctx(void* ctx, unsigned char* data, 
-               unsigned int dataLength);
-
-/**
- * Update the Skein384 context with several data chunks.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param dataChunks
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- *    Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein384Ctx(void* ctx, unsigned char* dataChunks[],
-               unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
deleted file mode 100644
index b4234e5..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac256.h>
-
-void macSkein256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    macSkein(key, keyLength, data, dataLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-
-void macSkein256( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
-    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void* createMacSkein256Context(uint8_t* key, int32_t keyLength)
-{
-    return createSkeinMacContext(key, keyLength, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void freeMacSkein256Context(void* ctx)
-{
-    freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
deleted file mode 100644
index e87a1e1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/**
- * Methods to compute a Skein256 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN256_H
-#define HMAC_SKEIN256_H
-
-/**
- * @file skeinMac256.h
- * @brief Function that provide Skein256 HMAC support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH 32
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein256 HMAC.
- *
- * This functions takes one data chunk and computes its Skein256 HMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein256 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein256 HAMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
deleted file mode 100644
index 57c7ad1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH  48
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac384.h>
-
-void macSkein384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    macSkein(key, keyLength, data, dataLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-
-void macSkein384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
-    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void* createMacSkein384Context(uint8_t* key, int32_t keyLength)
-{
-    return createSkeinMacContext(key, keyLength, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void freeMacSkein384Context(void* ctx)
-{
-    freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
deleted file mode 100644
index 2065899..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/**
- * Methods to compute a Skein384 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN384_H
-#define HMAC_SKEIN384_H
-
-/**
- * @file skeinMac384.h
- * @brief Function that provide Skein384 HMAC support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH 48
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein384 HMAC.
- *
- * This functions takes one data chunk and computes its Skein384 HMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein384 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein384 HAMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h b/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
index 595d19d..e063a35 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
+++ b/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
index d718f24..e602dd3 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;
-    EcCurve curve;
+    NistECpCurve curve;
     EcPoint pubPoint;
 } dhCtx;
 
@@ -202,12 +202,6 @@
     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;
     }
@@ -252,16 +246,6 @@
         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;
     }
 }
 
@@ -283,11 +267,6 @@
     case EC38:
         ecFreeCurveNistECp(&tmpCtx->curve);
         break;
-
-    case E255:
-    case E414:
-        ecFreeCurvesCurve(&tmpCtx->curve);
-        break;
     }
 }
 
@@ -321,7 +300,7 @@
         return length;
     }
 
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
+    if (pkType == EC25 || pkType == EC38) {
         int32_t len = getPubKeySize() / 2;
         EcPoint pub;
 
@@ -340,23 +319,6 @@
 
         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;
 }
 
@@ -376,10 +338,7 @@
 
     case EC25:
     case EC38:
-    case E255:
-    case E414:
-        while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))
-            ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
+        return ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey);
     }
     return 0;
 }
@@ -400,13 +359,6 @@
     case EC38:
         return 48;
         break;
-
-    case E255:
-        return 32;
-        break;
-    case E414:
-        return 52;
-        break;
     }
     return 0;
 }
@@ -417,11 +369,9 @@
     if (pkType == DH2K || pkType == DH3K)
         return bnBytes(&tmpCtx->pubKey);
 
-    if (pkType == EC25 || pkType == EC38 || pkType == E414)
-        return bnBytes(tmpCtx->curve.p) * 2;   // *2 -> x and y coordinate
+    if (pkType == EC25 || pkType == EC38)
+        return bnBytes(tmpCtx->curve.p) * 2;
 
-    if (pkType == E255)
-        return bnBytes(tmpCtx->curve.p);
     return 0;
 
 }
@@ -441,18 +391,13 @@
         return size;
     }
 
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
+    if (pkType == EC25 || pkType == EC38) {
         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;
 }
 
@@ -460,22 +405,49 @@
 {
 
     /* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
+    if (pkType == EC25 || pkType == EC38) {
 
+        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);
 
-        return ecCheckPubKey(&tmpCtx->curve, &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) {
+            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;
 
-    if (pkType == E255) {
-        return 1;
+    fail:
+        FREE_EC_POINT(&pub);
+        bnEnd(&t1);
+        bnEnd(&t2);
+        return ret;
     }
 
     BigNum pubKeyOther;
@@ -509,16 +481,16 @@
     switch (pkType) {
     case DH2K:
         return dh2k;
+        break;
     case DH3K:
         return dh3k;
+        break;
     case EC25:
         return ec25;
+        break;
     case EC38:
         return ec38;
-    case E255:
-        return e255;
-    case E414:
-        return e414;
+        break;
     }
     return NULL;
 }
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
index d2a3a40..acf0e92 100644
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
+++ b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
@@ -59,8 +59,6 @@
 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/zrtp/libzrtpcpp/ZIDCache.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
index 2ba1de6..8f471a6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -161,9 +161,9 @@
     /**
      * @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.
+     * 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.
      *
      */
     virtual void cleanup() =0;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
index 7aa6dd0..6b1d70b 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
index 7b264e8..9d43fde 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
index c46fc24..f3d804e 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -19,7 +19,7 @@
 #define _ZIDRECORD_H_
 
 #include <stdint.h>
-#include <common/osSpecifics.h>
+
 /**
  * @file ZIDRecord.h
  * @brief ZID cache record management
@@ -32,6 +32,19 @@
  * @{
  */
 
+#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.
  */
@@ -52,12 +65,6 @@
 
 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 111b4ed..28287d9 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
index 74cc8a0..579a430 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
index a20b599..417a892 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2012 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -51,15 +51,6 @@
 #define MAX_DIGEST_LENGTH       64
 #define IMPL_MAX_DIGEST_LENGTH  64
 
-// max. number of parallel supported ZRTP protocol versions.
-#define MAX_ZRTP_VERSIONS       2
-
-// currently only 1.10 supported
-#define SUPPORTED_ZRTP_VERSIONS       1
-
-// Integer representation of highest supported ZRTP protocol version
-#define HIGHEST_ZRTP_VERION    12
-
 class __EXPORT ZrtpStateClass;
 class ZrtpDH;
 
@@ -117,14 +108,6 @@
         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
@@ -236,25 +219,17 @@
     /**
      * Get the ZRTP Hello Hash data.
      *
-     * Use this method to get the ZRTP Hello hash data. The method
+     * Use this method to get the ZRTP Hello Hash data. The method
      * returns the data as a string containing the ZRTP protocol version and
      * hex-digits.
-     * 
-     * The index defines which Hello packet to use. Each supported ZRTP procol version
-     * uses a different Hello packet and thus computes different hashes.
      *
      * Refer to ZRTP specification, chapter 8.
-     * 
-     * @param index
-     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < MAX_ZRTP_VERSIONS.
      *
      * @return
-     *    a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'
-     *    SDP attribute identifier. The hello hash is available immediately after class instantiation.
-     * 
-     * @see getNumberSupportedVersions()
+     *    a std:string containing the Hello hash value as hex-digits. The
+     *    hello hash is available immediately after class instantiation.
      */
-    std::string getHelloHash(int index);
+    std::string getHelloHash();
 
     /**
      * Get the peer's ZRTP Hello Hash data.
@@ -515,28 +490,6 @@
       */
      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;
 
@@ -659,6 +612,7 @@
     uint8_t H1[IMPL_MAX_DIGEST_LENGTH];
     uint8_t H2[IMPL_MAX_DIGEST_LENGTH];
     uint8_t H3[IMPL_MAX_DIGEST_LENGTH];
+    uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];
 
     uint8_t peerHelloHash[IMPL_MAX_DIGEST_LENGTH];
     uint8_t peerHelloVersion[ZRTP_WORD_SIZE + 1];   // +1 for nul byte
@@ -816,9 +770,7 @@
     /**
      * Pre-initialized packets.
      */
-    ZrtpPacketHello    zrtpHello_11;
-    ZrtpPacketHello    zrtpHello_12;   // Prepare for ZRTP protocol version 1.2
-
+    ZrtpPacketHello    zrtpHello;
     ZrtpPacketHelloAck zrtpHelloAck;
     ZrtpPacketConf2Ack zrtpConf2Ack;
     ZrtpPacketClearAck zrtpClearAck;
@@ -834,24 +786,12 @@
     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];
@@ -998,75 +938,20 @@
     bool checkMultiStream(ZrtpPacketHello* hello);
 
     /**
-     * Checks if Hello packet contains a strong (384bit) hash based on selection policy.
-     * 
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST HASH algorithms (Skein etc).
-     * 
-     * If Hello packet does not contain a strong hash then this functions returns @c NULL.
+     * Checks if Hello packet contains a strong (384bit) hash and returns it.
      *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
      * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.
      */
-    AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName);
+    AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello);
 
     /**
-     * Checks if Hello packet offers a strong (256bit) symmetric cipher based on selection policy.
+     * Checks if Hello packet offers a strong (256bit) symmetric cipher.
      *
-     * 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.
+     * The method returns the first strong cipher offered in the Hello packet.
      *
      * @return @c cipher algorithm if found in Hello packet, @c NULL otherwise.
      */
-    AlgorithmEnum* getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet contains a hash based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST HASH algorithms (Skein etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return @c hash algorithm found in Hello packet.
-     */
-    AlgorithmEnum* getHashOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet offers a symmetric cipher based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST symmetric cipher algorithms (Twofish etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return non-NIST @c cipher algorithm if found in Hello packet, @c NULL otherwise
-     */
-    AlgorithmEnum* getCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet offers a SRTP authentication length based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST algorithms (Skein etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName algoName name of selected PK algorithm
-     * @return @c authLen algorithm found in Hello packet
-     */
-    AlgorithmEnum* getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName);
+    AlgorithmEnum* getStrongCipherOffered(ZrtpPacketHello *hello);
 
     /**
      * Save the computed MitM secret to the ZID record of the peer
@@ -1080,8 +965,6 @@
 
     void computeSharedSecretSet(ZIDRecord *zidRec);
 
-    void computeAuxSecretIds();
-
     void computeSRTPKeys();
 
     void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
@@ -1462,10 +1345,8 @@
       *
       * @param id
       *     The client's id
-      * @param hpv
-      *     Pointer to hello packet version structure.
       */
-     void setClientId(std::string id, HelloPacketVersion* hpv);
+     void setClientId(std::string id);
 };
 
 /**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
index 0ad5b95..19aebb0 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) 2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
@@ -565,7 +565,7 @@
      * @returns
      *      Pointer to the ZrtpContext
      */
-    ZrtpContext* zrtp_CreateWrapper(void);
+    ZrtpContext* zrtp_CreateWrapper();
 
     /**
      * Initialize the ZRTP protocol engine.
@@ -782,28 +782,21 @@
      *
      * Use this method to get the ZRTP Hello Hash data. The method
      * returns the data as a string containing the ZRTP protocol version and
-     * hex-digits. 
-
-     * The index defines which Hello packet to use. Each supported ZRTP procol version
-     * uses a different Hello packet and thus computes different hashes.
+     * hex-digits. Refer to ZRTP specification, chapter 8.
      *
-     * Refer to ZRTP specification, chapter 8.
-     *
-     * @param index
-     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < zrtp_getNumberSupportedVersions().
+     * <b>NOTE: An application may call this method if it needs this information.
+     * Usually it is not necessary.</b>
      *
      * @param zrtpContext
      *    Pointer to the opaque ZrtpContext structure.
-     *
      * @return
-     *    a pointer to a C-string that contains the Hello hash formatted according to RFC6189 section 8 
-     *    without the leading 'a=zrtp-hash:' SDP attribute identifier. The hello hash is available 
-     *    immediately after @c zrtp_CreateWrapper. The caller must @c free() if it does not use the
+     *    a pointer to a C-string that contains the Hello hash value as
+     *    hex-digits. The hello hash is available immediately after
+     *    @c zrtp_CreateWrapper .
+     *    The caller must @c free() if it does not use the
      *    hello hash C-string anymore.
-     *
-     * @see zrtp_getNumberSupportedVersions()
      */
-    char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index);
+    char* zrtp_getHelloHash(ZrtpContext* zrtpContext);
 
     /**
      * Get the peer's ZRTP Hello Hash data.
@@ -1077,27 +1070,7 @@
     int32_t zrtp_getPeerZid(ZrtpContext* zrtpContext, uint8_t* data);
 
 
-     /**
-      * Get number of supported ZRTP protocol versions.
-      *
-      * @param zrtpContext
-      *    Pointer to the opaque ZrtpContext structure.
-      *
-      * @return the number of supported ZRTP protocol versions.
-      */
-     int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext);
-
-     /**
-      * Get negotiated ZRTP protocol versions.
-      *
-      * @param zrtpContext
-      *    Pointer to the opaque ZrtpContext structure.
-      *
-      * @return the integer representation of the negotiated ZRTP protocol version.
-      */
-     int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext);
-
-     /**
+    /**
      * This enumerations list all configurable algorithm types.
      */
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
index 0ad18a9..957c4dd 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -28,7 +28,19 @@
 #include <string>
 #include <stdint.h>
 #include <libzrtpcpp/ZrtpCodes.h>
-#include <common/osSpecifics.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
 
 /**
  * This enum defines which role a ZRTP peer has.
@@ -46,7 +58,6 @@
  * </ul>
  */
 typedef enum  {
-    NoRole = 0,     ///< ZRTP role not yet set
     Responder = 1,  ///< This client is in ZRTP Responder mode
     Initiator       ///< This client is in ZRTP Initiator mode
 } Role;
@@ -118,10 +129,9 @@
      * ZRTP calls this method to send a ZRTP packet via the RTP session.
      *
      * @param data
-     *    Points to ZRTP packet to send. The packet already contains a 4 bytes
-     *    storage at the end to store CRC.
+     *    Points to ZRTP packet to send.
      * @param length
-     *    The length in bytes of the data, including the CRC storage.
+     *    The length in bytes of the data
      * @return
      *    zero if sending failed, one if packet was send
      */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
index 098ec06..dd739e0 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-2013 Werner Dittmann
+    Copyright (C) 2010 Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
index 1a7dd5f..b35d47b 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-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the Lesser GNU General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -90,15 +90,14 @@
  * Sub-codes for Warning
  */
 enum WarningCodes {
-    WarningDHAESmismatch = 1,       //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded
+    WarningDHAESmismatch = 1,       //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096
     WarningGoClearReceived,         //!< Received a GoClear message
-    WarningDHShort,                 //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded
+    WarningDHShort,                 //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096
     WarningNoRSMatch,               //!< No retained shared secrets available - must verify SAS
     WarningCRCmismatch,             //!< Internal ZRTP packet checksum mismatch - packet dropped
     WarningSRTPauthError,           //!< Dropping packet because SRTP authentication failed!
     WarningSRTPreplayError,         //!< Dropping packet because SRTP replay check failed!
-    WarningNoExpectedRSMatch,       //!< Valid retained shared secrets availabe but no matches found - must verify SAS
-    WarningNoExpectedAuxMatch       //!< Our AUX secret was set but the other peer's AUX secret does not match ours
+    WarningNoExpectedRSMatch        //!< Valid retained shared secrets availabe but no matches found - must verify SAS
 };
 
 /**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
index bb78cef..896a85f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2009 - 2013 Werner Dittmann
+  Copyright (C) 2009 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -315,14 +315,6 @@
     ~ZrtpConfigure();
 
     /**
-     * Define the algorithm selection policies.
-     */
-    typedef enum _policies {
-        Standard = 1,
-        PreferNonNist = 2
-    } Policy;
-
-    /**
      * Set the maximum number of algorithms per algorithm type that an application can
      * configure.
      */
@@ -518,9 +510,6 @@
     /// Helper function to print some internal data
     void printConfiguredAlgos(AlgoTypes algoTyp);
 
-    Policy getSelectionPolicy()         {return selectionPolicy;}
-    void setSelectionPolicy(Policy pol) {selectionPolicy = pol;}
-
   private:
     std::vector<AlgorithmEnum* > hashes;
     std::vector<AlgorithmEnum* > symCiphers;
@@ -543,8 +532,6 @@
 
     void printConfiguredAlgos(std::vector<AlgorithmEnum* >& a);
 
-    Policy selectionPolicy;
-
   protected:
 
   public:
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
index 49eec83..ad57edd 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
index a5826c7..11b7930 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -38,8 +38,12 @@
 #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 91ca4c4..992f6d8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
index 4b6e1eb..b23b23d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -31,11 +31,6 @@
 
 #include <libzrtpcpp/ZrtpPacketBase.h>
 
-// PRSH here only for completeness. We don't support PRSH in the other ZRTP parts.
-#define COMMIT_DH_EX      29
-#define COMMIT_MULTI      25
-#define COMMIT_PRSH       27
-
 /**
  * Implement the Commit packet.
  *
@@ -53,11 +48,6 @@
     Commit_t* commitHeader;     ///< Points to Commit message part
 
  public:
-    typedef enum _commitType {
-        DhExchange =  1,
-        MultiStream = 2
-    } commitType;
-
     /// Creates a Commit packet with default data
     ZrtpPacketCommit();
 
@@ -100,10 +90,6 @@
     /// Get pointer to MAC field during multi-stream mode, a fixed length byte array
     uint8_t* getHMACMulti()   { return commitHeader->hmac-4*ZRTP_WORD_SIZE; };
 
-    /// Check if packet length makes sense.
-    bool isLengthOk(commitType type)   {int32_t len = getLength(); 
-                                        return ((type == DhExchange) ? len == COMMIT_DH_EX : len == COMMIT_MULTI);}
-
     /// Set hash algorithm type field, fixed length character field
     void setHashType(uint8_t* text)    { memcpy(commitHeader->hash, text, ZRTP_WORD_SIZE); };
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
index a6f85f5..a7c2567 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
index 283861d..e3ff85b 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -84,11 +84,6 @@
         /// get the signature length in words
         int32_t getSignatureLength();
 
-        /// Check if packet length makes sense. Confirm packets are 19 words at minumum
-        bool isLengthOk()             {return (getLength() >= 19); }
-
-        bool isSignatureLengthOk();
-
         /// set SAS verified flag
         void setSASFlag()            { confirmHeader->flags |= 0x4; }
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
index 08737a5..d0ea4ba 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -79,9 +79,6 @@
     /// Get pointer to HMAC, fixed length byte array
     uint8_t* getHMAC()           { return pv+dhLength; };
 
-    /// Check if packet length makes sense. DHPart packets are 29 words at minumum, using E255
-    bool isLengthOk()            {return (getLength() >= 29);}
-
     /// Setpublic key value, variable length byte array
     void setPv(uint8_t* text)         { memcpy(pv, text, dhLength); };
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
index 679a803..ca00ee0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
index cfd435c..e64c8a6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2007-2013 Werner Dittmann
+  Copyright (C) 2007 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
index f5394af..c9a38bd 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2012 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -85,9 +85,6 @@
     /// Get version number from Hello message, fixed ASCII character array
     uint8_t* getVersion()  { return helloHeader->version; };
 
-     /// Get version number from Hello message as integer, only relvant digits converted
-    int32_t getVersionInt();
-
     /// Get client id from Hello message, fixed ASCII character array
     uint8_t* getClientId() { return helloHeader->clientId; };
 
@@ -98,7 +95,7 @@
     uint8_t* getZid()      { return helloHeader->zid; };
 
     /// Set version sting in Hello message, fixed ASCII character array
-    void setVersion(const uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
+    void setVersion(uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
 
     /// Set client id in Hello message, fixed ASCII character array
     void setClientId(const uint8_t *t) { memcpy(helloHeader->clientId, t, sizeof(helloHeader->clientId)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
index d3e138e..345a071 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
index 32fb2f9..840df62 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
index eb2924f..b795ffb 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
index 7fe373b..93437e6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2007-2013 Werner Dittmann
+  Copyright (C) 2007 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
index 22739ff..04721fa 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2011 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -73,14 +73,11 @@
         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
new file mode 100644
index 0000000..7a1ee67
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
@@ -0,0 +1,911 @@
+/*
+  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/zrtp/libzrtpcpp/ZrtpSdesStream.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
index d7d2265..7d36f2b 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
@@ -1,107 +1,13 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTPSDESSTREAM_H_
-#define _ZRTPSDESSTREAM_H_
-/**
- * @file ZrtpSdesStream.h
- * @brief The ZRTP main engine
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- *
- * This class implements SDES and provides a simple to use API for applications.
- *
- * This SDES implementation currently supports only two SDES algorithms and it does
- * not support optional parameters such as lifetime or MKI parameters. Also session
- * parameters are not supported. Most applications that use SDES don't use these
- * optional parameters.
- *
- * It is not necessary to explicitly start the SDES stream. The class initiates
- * the SRTP after it created and parsed all necessary SDES crypto strings.
- *
- * Because SDES works together with the signaling protocol, for example SIP, it is
- * important to adhere to a defined flow. The following pseudo code snippet depicts
- * such a flow. Applications shall follow this flow.
- *
- *<pre>
- *
- *     Inviter                           Answerer
- *    (Offerer)
- *
- * ZrtpSdesStream inv;                 ZrtpSdesStream answ;
- *
- * // create/get own SDES data
- * inv.createSdes(...);
- * inv.getCryptoMixAttribute(...)
- *
- * // prepare SIP/SDP offer, send
- * // it to answerer
- *                                    // receive SIP/SDP, get
- *                                    // SDES data, parse/set it
- *                                    answ.setCryptoMixAttribute(...)
- *                                    answ.parseSdes(...)
- *
- *                                    // create/get own SDES data
- *                                    answ.getCryptoMixAttribute(...)
- *                                    answ.createSdes(...)
- *
- *                                    // prepare SIP/SDP answer,
- *                                    // send to offerer
- * // receive SIP/SDP answer, get
- * // SDES data, parse, set mix algo
- * // if availabe
- * inv.setCryptoMixAttribute(...)
- * inv.parseSdes(...)
- *
- * ...                                ...
- *
- * inv.outgoingRtp(...)
- *                                    answ.incomingRtp(...)
- *
- *                                    answ.outgoingRtp(...)
- * inv.incomingRtp(...)
- *</pre>
- *
- * To use SDES without the new crypto mix feature just do not use the crypto mix functions.
- * An application may always send crypto mix attributes. If the answerer does not support this
- * feature it does not send back a selected algorithm and the offerer cannot set an algorithm.
- * Thus the crypto mix feature is not used.
- * 
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <common/osSpecifics.h>
 
 class CryptoContext;
 class CryptoContextCtrl;
 
-/*
- * These functions support 256 bit encryption algorithms.
- */
-#define MAX_KEY_LEN           32
-#define MAX_SALT_LEN          14
-#define MAX_DIGEST_LENGTH     64
-
 /**
  * Maximum length of a raw crypto string.
  */
 #define MAX_CRYPT_STRING_LEN 200
 
-class __EXPORT ZrtpSdesStream {
+class ZrtpSdesStream {
 
 public:
 
@@ -109,12 +15,12 @@
      * Supported SDES crypto suites.
      */
     typedef enum {
-        AES_CM_128_HMAC_SHA1_32 = 0,
+        AES_CM_128_HMAC_SHA1_32 = 1,
         AES_CM_128_HMAC_SHA1_80
     } sdesSuites;
 
     /**
-     * SDES stream state
+     * SDES stream stated
      */
     typedef enum {
         STREAM_INITALIZED = 1,
@@ -123,18 +29,15 @@
         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.
      */
@@ -164,16 +67,19 @@
      * @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The
      * answering application's SRTP environment is now ready.
      *
-     * @param cryptoString output buffer that receives the crypto  string in raw
-     *                     format, without the any signaling prefix, for example
-     *                     @c a=crypto:. The function terminates the crypto string
-     *                     with a @c nul byte
+     * @param cryptoString points to a char output buffer that receives the
+     *                     crypto  string in the raw format, without the any
+     *                     signaling prefix, for example @c a=crypto: in case
+     *                     of SDP signaling. The function terminates the
+     *                     crypto string with a @c nul byte
      *
      * @param maxLen length of the crypto string buffer. On return it contains the
      *               actual length of the crypto string.
      *
-     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
-     *                  set it to @c false.
+     * @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).
      *
      * @return @c true if data could be created, @c false otherwise.
      */
@@ -182,67 +88,36 @@
     /**
      * @brief Parses an SDES crypto string for the SDES/ZRTP stream.
      *
-     * Parses a SDES crypto string that the application received in a SIP INVITE
+     * Parses a received crypto string that the application received in a SIP INVITE
      * or SIP 200 OK.
      *
-     * An INVITE-ing (offerer) application shall call this function right after it received
+     * An INVITE-ing application shall call this function right after it received
      * the 200 OK from the answering application and must call this function with the
-     * @c sipInvite parameter set to @c true. The offerer's SRTP is now ready for use.
+     * @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.
      *
      * 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.
+     * @c sipInvite parameter set to @c false. This is usually the same point when
+     * it gets the @c zrtp-hash from the SDP parameters.
      *
-     * @param cryptoString the received crypto sting in raw format,
-     *                     without any signaling prefix, for example @c a=crypto:
+     * @param cryptoString points to the crypto sting in raw format,
+     *                     without any signaling prefix, for example @c
+     *                     a=crypto: in case of SDP signaling.
      *
      * @param length length of the crypto string to parse. If the length is
      *               @c zero then the function uses @c strlen to compute
      *               the length.
      *
-     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
-     *                  set it to @c false.
+     * @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).
      *
      * @return @c true if data could be created, @c false otherwise.
      */
-    bool parseSdes(const char *cryptoString, size_t length, bool sipInvite);
-
-    /**
-     * @brief Get Crypto Mix attribute string
-     *
-     * The offerer calls this method to get a string of @b all supported crypto mix algorithms
-     * and shall send this list to the answerer.
-     *
-     * The answerer calls this function only @b after it received the crypto mix string and @b after
-     * calling @c setCryptoMixAttribute(...). The method returns only one (the selected)
-     * crypto mix algorithm and the answerer must send this to the offerer, for example in 200 OK.
-     *
-     * @param algoNames buffer to store the nul terminated crypto mix algorithm names.
-     *                  The buffer must be long enough to hold at least the name of the mandatory
-     *                  algorithm HMAC-SHA-384.
-     *
-     * @param length length of buffer
-     *
-     * @return Length of algorithm names (excluding nul byte) or zero if crypto mix not supported or
-     *         enabled.
-     */
-    int getCryptoMixAttribute(char *algoNames, size_t length);
-
-    /**
-     * @brief Set Crypto Mix attribute string
-     *
-     * The method checks if it the string contains an supported algorithm and selects one algorithm.
-     *
-     * The offerer calls this method @b after it received the selected algorithm in the answer.
-     *
-     * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method.
-     *
-     * @param algoNames buffer that contains the received crypto mix algorithm names.
-     *                  The buffer must be nul terminated.
-     *
-     * @return @c false if none of the offered algorithms is supported.
-     */
-    bool setCryptoMixAttribute(const char *algoNames);
+    bool parseSdes(char *cryptoString, size_t length, bool sipInvite);
 
     /*
      * ******** Outgoing RTP/RTCP packet handling
@@ -276,7 +151,7 @@
     /**
      * @brief Process an outgoing RTCP packet
      *
-     * This function works in the same way as @c outgoingRtp.
+     * This function works in the same way as @c sdesZrtpProcessRtp.
      *
      * @param packet the buffer that contains the RTCP packet. After processing, the
      *               encrypted packet is stored in the same buffer. The buffer must
@@ -310,7 +185,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 RTP packet
+     * @param length length of the RTCP packet
      *
      * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
      *
@@ -324,7 +199,7 @@
     /**
      * @brief Process an incoming RTCP or SRTCP packet
      *
-     * This function works in the same way as @c incomingRtp.
+     * This function works in the same way as @c sdesZrtpProcessSrtp.
      *
      * @param packet the buffer that contains the RTCP/SRTCP packet. After processing,
      *               the decrypted packet is stored in the same buffer.
@@ -341,64 +216,21 @@
     int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength);
 
     /**
-     * @brief Process an outgoing ZRTP packet.
-     * 
-     * Works like @c outgoingRtp, refer to that documentation.
-     * 
-     * @param packet the buffer that contains the ZRTP packet.
-     *
-     * @param length length of the ZRTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet including SRTP data.
-     *
-     * @return
-     *  - @c true if encryption is successful, app shall send packet to the recipient.
-     *  - @c false if there was an error during encryption, don't send the packet.
-     */
-    bool outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
-    /**
-     * @brief Process an incoming ZRTP packet
-     *
-     * Works like @c incomingRtp, refer to that documentation.
-     *
-     * @param packet the buffer that contains the ZRTP/SRTP packet. After processing,
-     *               the decrypted packet is stored in the same buffer.
-     *
-     * @param length length of the RTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
-     *
-     * @return
-     *       - 1: success,
-     *       - -1: SRTP authentication failed,
-     *       - -2: SRTP replay check failed
-     */
-    int incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
-        /**
-     * @brief Return state of SDES stream.
+     * Return state of SDES stream.
      *
      * @return state of stream.
      */
     sdesZrtpStates getState() {return state;}
 
     /**
-     * @brief Return SDES crypto mixer HMAC type.
-     *
-     * @return HMAC type
-     */
-    sdesHmacTypeMix getHmacTypeMix() {return cryptoMixHashType;}
-
-    /**
-     * @brief Return name of active cipher algorithm.
+     * Return name of active cipher algorithm.
      *
      * @return point to name of cipher algorithm.
      */
     const char* getCipher();
 
     /**
-     * @brief Return name of active SRTP authentication algorithm.
+     * Return name of active SRTP authentication algorithm.
      *
      * @return point to name of authentication algorithm.
      */
@@ -412,9 +244,11 @@
     /**
      * @brief Create an SRTP crypto context and the according SDES crypto string.
      *
-     * This lower layer method creates an SDES crypto string. It selects a valid
-     * crypto suite, generates the key and salt data, converts these into base 64
-     * and returns the crypto string in raw format without any signaling prefixes.
+     * 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.
      *
      * The output string has the following format:
      * @verbatim
@@ -457,7 +291,8 @@
      *
      * 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.
+     * 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.
      *
      * Applications usually don't use this method directly. Applications shall
      * use the SDES stream functions.
@@ -489,28 +324,6 @@
      */
     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;
@@ -520,28 +333,4 @@
     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 5c16313..c1887c9 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -161,11 +161,6 @@
      */
     bool subEvWaitRelayAck();
 
-    /**
-     * Hello packet version sent to other partner
-     */
-    int32_t sentVersion;
-
 public:
     /// Create a ZrtpStateClass
     ZrtpStateClass(ZRtp *p);
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
index e90a543..44662a0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
index 0be1e56..91b26c1 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -37,12 +37,8 @@
  *
  * @author Werner Dittmann <Werner.Dittmann@t-online.de>
  */
-
-extern char zrtpBuildInfo[];
-
 extern char clientId[];
-extern char zrtpVersion_11[];
-extern char zrtpVersion_12[];
+extern char zrtpVersion[];
 
 /**
  *
@@ -91,8 +87,6 @@
 
 extern char s256[];
 extern char s384[];
-extern char skn2[];
-extern char skn3[];
 extern const char* mandatoryHash;
 
 extern char aes3[];
@@ -108,8 +102,6 @@
 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 d3c9f9d..3e4871c 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
@@ -1,8 +1,8 @@
 /*

-  Copyright (C) 2006-2013 Werner Dittmann

+  Copyright (C) 2006-2008 Werner Dittmann

 

   This program is free software: you can redistribute it and/or modify

-  it under the terms of the GNU Lesser General Public License as published by

+  it under the terms of the GNU General Public License as published by

   the Free Software Foundation, either version 3 of the License, or

   (at your option) any later version.

 

diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
index 8f33462..b49622e 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
@@ -1,19 +1,6 @@
 /*
-  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_
@@ -292,11 +279,11 @@
 
 
     /**
-     * @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.
+     * 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.
      *
      * @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 f01fb52..18ba7a1 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
new file mode 100644
index 0000000..3eae183
--- /dev/null
+++ b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
@@ -0,0 +1,76 @@
+/*
+  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/zrtp/zrtpCacheSqliteBackend.c b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
index 7dc9cdf..d73c88d 100644
--- a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
+++ b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
@@ -1,22 +1,4 @@
 /*
-  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>
@@ -24,7 +6,6 @@
 #include <stdint.h>
 #include <string.h>
 #include <time.h>
-#include <sqlite3.h>
 
 #include <crypto/zrtpDH.h>
 
@@ -74,8 +55,6 @@
 /* *****************************************************************************
  * 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));";
 
@@ -596,29 +575,11 @@
 
 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)
 {
@@ -774,7 +735,6 @@
 {
     ops->openCache = openCache;
     ops->closeCache = closeCache;
-    ops->cleanCache = clearCache;
 
     ops->readLocalZid = readLocalZid;