* #40116: Switch to 2.3.0 libzrtpcpp version
diff --git a/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
new file mode 100644
index 0000000..4e03f28
--- /dev/null
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
@@ -0,0 +1,1292 @@
+/*
+  Copyright (C) 2006-2010 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _ZRTP_H_
+#define _ZRTP_H_
+/**
+ * @file ZRtp.h
+ * @brief The ZRTP main engine
+ * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
+ * @{
+ */
+
+#include <cstdlib>
+
+#include <libzrtpcpp/ZrtpPacketHello.h>
+#include <libzrtpcpp/ZrtpPacketHelloAck.h>
+#include <libzrtpcpp/ZrtpPacketCommit.h>
+#include <libzrtpcpp/ZrtpPacketDHPart.h>
+#include <libzrtpcpp/ZrtpPacketConfirm.h>
+#include <libzrtpcpp/ZrtpPacketConf2Ack.h>
+#include <libzrtpcpp/ZrtpPacketGoClear.h>
+#include <libzrtpcpp/ZrtpPacketClearAck.h>
+#include <libzrtpcpp/ZrtpPacketError.h>
+#include <libzrtpcpp/ZrtpPacketErrorAck.h>
+#include <libzrtpcpp/ZrtpPacketPing.h>
+#include <libzrtpcpp/ZrtpPacketPingAck.h>
+#include <libzrtpcpp/ZrtpPacketSASrelay.h>
+#include <libzrtpcpp/ZrtpPacketRelayAck.h>
+#include <libzrtpcpp/ZrtpCallback.h>
+#include <libzrtpcpp/ZIDRecord.h>
+
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32
+#endif
+
+// Prepare to support digest algorithms up to 512 bit (64 bytes)
+#define MAX_DIGEST_LENGTH       64
+#define IMPL_MAX_DIGEST_LENGTH  64
+
+class __EXPORT ZrtpStateClass;
+class ZrtpDH;
+
+/**
+ * The main ZRTP class.
+ *
+ * This is the main class of the RTP/SRTP independent part of the GNU
+ * ZRTP. It handles the ZRTP HMAC, DH, and other data management. The
+ * user of this class needs to know only a few methods and needs to
+ * provide only a few external functions to connect to a Timer
+ * mechanism and to send data via RTP and SRTP. Refer to the
+ * ZrtpCallback class to get detailed information regading the
+ * callback methods required by GNU RTP.
+ *
+ * The class ZrtpQueue is the GNU ccRTP specific implementation that
+ * extends standard ccRTP RTP provide ZRTP support. Refer to the
+ * documentation of ZrtpQueue to get more information about the usage
+ * of ZRtp and associated classes.
+ *
+ * The main entry into the ZRTP class is the processExtensionHeader()
+ * method.
+ *
+ * This class does not directly handle the protocol states, timers,
+ * and packet resend. The protocol state engine is responsible for
+ * these actions.
+ *
+ * Example how to use ZRtp:
+ *<pre>
+ *    zrtpEngine = new ZRtp((uint8_t*)ownZid, (ZrtpCallback*)this, idString);
+ *    zrtpEngine->startZrtpEngine();
+ *</pre>
+ * @see ZrtpCallback
+ *
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+class __EXPORT ZRtp {
+
+    public:
+
+    /**
+     * Constructor intializes all relevant data but does not start the
+     * engine.
+     */
+    ZRtp(uint8_t* myZid, ZrtpCallback* cb, std::string id,
+         ZrtpConfigure* config, bool mitmm= false, bool sasSignSupport= false);
+
+    /**
+     * Destructor cleans up.
+     */
+    ~ZRtp();
+
+    /**
+     * Kick off the ZRTP protocol engine.
+     *
+     * This method calls the ZrtpStateClass#evInitial() state of the state
+     * engine. After this call we are able to process ZRTP packets
+     * from our peer and to process them.
+     */
+    void startZrtpEngine();
+
+    /**
+     * Stop ZRTP security.
+     *
+     */
+    void stopZrtp();
+
+    /**
+     * Process RTP extension header.
+     *
+     * This method expects to get a pointer to the extension header of
+     * a RTP packet. The method checks if this is really a ZRTP
+     * packet. If this check fails the method returns 0 (false) in
+     * case this is not a ZRTP packet. We return a 1 if we processed
+     * the ZRTP extension header and the caller may process RTP data
+     * after the extension header as usual.  The method return -1 the
+     * call shall dismiss the packet and shall not forward it to
+     * further RTP processing.
+     *
+     * @param extHeader
+     *    A pointer to the first byte of the extension header. Refer to
+     *    RFC3550.
+     * @param peerSSRC
+     *    The peer's SSRC.
+     * @return
+     *    Code indicating further packet handling, see description above.
+     */
+    void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC);
+
+    /**
+     * Process a timeout event.
+     *
+     * We got a timeout from the timeout provider. Forward it to the
+     * protocol state engine.
+     *
+     */
+    void processTimeout();
+
+    /**
+     * Check for and handle GoClear ZRTP packet header.
+     *
+     * This method checks if this is a GoClear packet. If not, just return
+     * false. Otherwise handle it according to the specification.
+     *
+     * @param extHeader
+     *    A pointer to the first byte of the extension header. Refer to
+     *    RFC3550.
+     * @return
+     *    False if not a GoClear, true otherwise.
+     */
+    bool handleGoClear(uint8_t *extHeader);
+
+    /**
+     * Set the auxilliary secret.
+     *
+     * Use this method to set the auxilliary secret data. Refer to ZRTP
+     * specification, chapter 4.3 ff
+     *
+     * @param data
+     *     Points to the secret data.
+     * @param length
+     *     Length of the auxilliary secrect in bytes
+     */
+    void setAuxSecret(uint8_t* data, int32_t length);
+
+    /**
+     * Check current state of the ZRTP state engine
+     *
+     * @param state
+     *    The state to check.
+     * @return
+     *    Returns true id ZRTP engine is in the given state, false otherwise.
+     */
+    bool inState(int32_t state);
+
+    /**
+     * Set SAS as verified.
+     *
+     * Call this method if the user confirmed (verfied) the SAS. ZRTP
+     * remembers this together with the retained secrets data.
+     */
+    void SASVerified();
+
+    /**
+     * Reset the SAS verfied flag for the current active user's retained secrets.
+     *
+     */
+    void resetSASVerified();
+
+    /**
+     * Get the ZRTP Hello Hash data.
+     *
+     * Use this method to get the ZRTP Hello Hash data. The method
+     * returns the data as a string containing the ZRTP protocol version and
+     * hex-digits.
+     *
+     * Refer to ZRTP specification, chapter 8.
+     *
+     * @return
+     *    a std:string containing the Hello hash value as hex-digits. The
+     *    hello hash is available immediately after class instantiation.
+     */
+    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 4.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.
+     */
+    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 4.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 also
+     *     <code>getMultiStrParams()</code>
+     */
+    void setMultiStrParams(std::string parameters);
+
+    /**
+     * Check if this ZRTP session is a Multi-stream session.
+     *
+     * Use this method to check if this ZRTP instance uses multi-stream.
+     * Refer to chapters 4.2 and 4.4.2 in the ZRTP.
+     *
+     * @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 PBX trusted MitM key and the user
+     * accepts this request, 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);
+
+    /**
+     * 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
+     * started this ZRTP session. Can be set to true only if mitmMode is also true.
+     * 
+     * @return status of the enrollmentMode flag.
+     */
+    bool isEnrollmentMode();
+
+    /**
+     * Set 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();
+
+    /**
+     * 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, 32 bytes
+     * @param render the SAS rendering algorithm
+     */
+    bool sendSASRelayPacket(uint8_t* sh, std::string render);
+
+    /**
+     * 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 pointer to the byte array that contains the full
+     *         SAS hash.
+     */
+    uint8_t* getSasHash();
+
+    /**
+     * 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 5.7 and 7.2.
+     *
+     * The signature data must be set before ZRTP the application calls
+     * <code>start()</code>.
+     *
+     * @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_t* data, int32_t length);
+
+    /**
+     * Get signature data.
+     *
+     * This functions returns a pointer to the signature data that was receivied
+     * during ZRTP processing. Refer to chapters 5.7 and 7.2.
+     *
+     * The returned pointer points to volatile data that is valid only during the
+     * <code>checkSASSignature()</code> callback funtion. The application must copy
+     * the signature data if it will be used after the callback function returns.
+     *
+     * The signature data can be retrieved after ZRTP enters secure state.
+     * <code>start()</code>.
+     *
+     * @return
+     *    Pointer to signature data.
+     */
+    const uint8_t* getSignatureData();
+
+    /**
+     * Get length of signature data in number of bytes.
+     *
+     * This functions returns the length of signature data that was receivied
+     * during ZRTP processing. Refer to chapters 5.7 and 7.2.
+     *
+     * @return
+     *    Length in bytes of the received signature data. The method returns
+     *    zero if no signature data is avilable.
+     */
+    int32_t getSignatureLength();
+
+    /**
+     * Emulate a Conf2Ack packet.
+     *
+     * This method emulates a Conf2Ack packet. According to ZRTP specification
+     * the first valid SRTP packet that the Initiator receives must switch
+     * on secure mode. Refer to chapter 4 in the specificaton
+     *
+     */
+    void conf2AckSecure();
+
+     /**
+      * 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_t getPeerZid(uint8_t* data);
+
+private:
+     friend class ZrtpStateClass;
+
+    /**
+     * The state engine takes care of protocol processing.
+     */
+    ZrtpStateClass* stateEngine;
+
+    /**
+     * This is my ZID that I send to the peer.
+     */
+    uint8_t zid[IDENTIFIER_LEN];
+
+    /**
+     * The peer's ZID
+     */
+    uint8_t peerZid[IDENTIFIER_LEN];
+
+    /**
+     * The callback class provides me with the interface to send
+     * data and to deal with timer management of the hosting system.
+     */
+    ZrtpCallback* callback;
+
+    /**
+     * My active Diffie-Helman context
+     */
+    ZrtpDH* dhContext;
+
+    /**
+     * The computed DH shared secret
+     */
+    uint8_t* DHss;
+
+    /**
+     * My computed public key
+     */
+    uint8_t pubKeyBytes[400];
+    /**
+     * Length off public key
+     */
+//    int32_t pubKeyLen;
+    /**
+     * My Role in the game
+     */
+    Role myRole;
+
+    /**
+     * The human readable SAS value
+     */
+    std::string SAS;
+
+    /**
+     * The SAS hash for signaling and alike. Refer to chapters
+     * 4.5 and 7 how sasHash, sasValue and the SAS string are derived.
+     */
+    uint8_t sasHash[MAX_DIGEST_LENGTH];
+    /**
+     * The ids for the retained and other shared secrets
+     */
+    uint8_t rs1IDr[MAX_DIGEST_LENGTH];
+    uint8_t rs2IDr[MAX_DIGEST_LENGTH];
+    uint8_t auxSecretIDr[MAX_DIGEST_LENGTH];
+    uint8_t pbxSecretIDr[MAX_DIGEST_LENGTH];
+
+    uint8_t rs1IDi[MAX_DIGEST_LENGTH];
+    uint8_t rs2IDi[MAX_DIGEST_LENGTH];
+    uint8_t auxSecretIDi[MAX_DIGEST_LENGTH];
+    uint8_t pbxSecretIDi[MAX_DIGEST_LENGTH];
+
+    /**
+     * pointers to aux secret storage and length of aux secret
+     */
+    uint8_t* auxSecret;
+    int32_t auxSecretLength;
+
+    /**
+     * Record if valid rs1 and/or rs1 were found in the
+     * retaind secret cache.
+     */
+    bool rs1Valid;
+    bool rs2Valid;
+    /**
+     * My hvi
+     */
+    uint8_t hvi[MAX_DIGEST_LENGTH];
+
+    /**
+     * The peer's hvi
+     */
+    uint8_t peerHvi[8*ZRTP_WORD_SIZE];
+
+    /**
+     * Context to compute the SHA256 hash of selected messages.
+     * Used to compute the s0, refer to chapter 4.4.1.4
+     */
+    void* msgShaContext;
+    /**
+     * Commited Hash, Cipher, and public key algorithms
+     */
+    AlgorithmEnum* hash;
+    AlgorithmEnum* cipher;
+    AlgorithmEnum* pubKey;
+    /**
+     * The selected SAS type.
+     */
+    AlgorithmEnum* sasType;
+
+    /**
+     * The selected SAS type.
+     */
+    AlgorithmEnum* authLength;
+
+    /**
+     * The Hash images as defined in chapter 5.1.1 (H0 is a random value,
+     * not stored here). Need full SHA 256 lenght to store hash value but
+     * only the leftmost 128 bits are used in computations and comparisons.
+     */
+    uint8_t H0[IMPL_MAX_DIGEST_LENGTH];
+    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
+
+    // We get the peer's H? from the message where length is defined as 8 words
+    uint8_t peerH0[8*ZRTP_WORD_SIZE];
+    uint8_t peerH1[8*ZRTP_WORD_SIZE];
+    uint8_t peerH2[8*ZRTP_WORD_SIZE];
+    uint8_t peerH3[8*ZRTP_WORD_SIZE];
+
+    /**
+     * The SHA256 hash over selected messages
+     */
+    uint8_t messageHash[MAX_DIGEST_LENGTH];
+
+    /**
+     * The s0
+     */
+    uint8_t s0[MAX_DIGEST_LENGTH];
+
+    /**
+     * The new Retained Secret
+     */
+    uint8_t newRs1[MAX_DIGEST_LENGTH];
+
+    /**
+     * The GoClear HMAC keys and confirm HMAC key
+     */
+    uint8_t hmacKeyI[MAX_DIGEST_LENGTH];
+    uint8_t hmacKeyR[MAX_DIGEST_LENGTH];
+
+    /**
+     * The Initiator's srtp key and salt
+     */
+    uint8_t srtpKeyI[MAX_DIGEST_LENGTH];
+    uint8_t srtpSaltI[MAX_DIGEST_LENGTH];
+
+    /**
+     * The Responder's srtp key and salt
+     */
+    uint8_t srtpKeyR[MAX_DIGEST_LENGTH];
+    uint8_t srtpSaltR[MAX_DIGEST_LENGTH];
+
+    /**
+     * The keys used to encrypt/decrypt the confirm message
+     */
+    uint8_t zrtpKeyI[MAX_DIGEST_LENGTH];
+    uint8_t zrtpKeyR[MAX_DIGEST_LENGTH];
+
+    /**
+     * Pointers to negotiated hash and HMAC functions
+     */
+    void (*hashFunction)(unsigned char *data,
+            unsigned int data_length,
+            unsigned char *digest);
+
+    void (*hashListFunction)(unsigned char *data[],
+            unsigned int data_length[],
+            unsigned char *digest);
+
+    void (*hmacFunction)(uint8_t* key, uint32_t key_length,
+                uint8_t* data, int32_t data_length,
+                uint8_t* mac, uint32_t* mac_length);
+
+    void (*hmacListFunction)( uint8_t* key, uint32_t key_length,
+                           uint8_t* data[], uint32_t data_length[],
+                           uint8_t* mac, uint32_t* mac_length );
+
+    void* (*createHashCtx)();
+
+    void (*closeHashCtx)(void* ctx, unsigned char* digest);
+
+    void (*hashCtxFunction)(void* ctx, unsigned char* data,
+           unsigned int dataLength);
+
+    void (*hashCtxListFunction)(void* ctx, unsigned char* dataChunks[],
+           unsigned int dataChunkLength[]);
+
+    int32_t hashLength;
+
+    // Funtion pointers to implicit hash and hmac functions
+    void (*hashFunctionImpl)(unsigned char *data,
+            unsigned int data_length,
+            unsigned char *digest);
+
+    void (*hashListFunctionImpl)(unsigned char *data[],
+            unsigned int data_length[],
+            unsigned char *digest);
+
+    void (*hmacFunctionImpl)(uint8_t* key, uint32_t key_length,
+                uint8_t* data, int32_t data_length,
+                uint8_t* mac, uint32_t* mac_length);
+
+    void (*hmacListFunctionImpl)( uint8_t* key, uint32_t key_length,
+                           uint8_t* data[], uint32_t data_length[],
+                           uint8_t* mac, uint32_t* mac_length );
+
+    int32_t hashLengthImpl;
+
+    /**
+     * The ZRTP Session Key
+     * Refer to chapter 5.4.1.4
+     */
+    uint8_t zrtpSession[MAX_DIGEST_LENGTH];
+
+    /**
+     * True if this ZRTP instance uses multi-stream mode.
+     */
+    bool multiStream;
+
+        /**
+     * True if the other ZRTP client supports multi-stream mode.
+     */
+    bool multiStreamAvailable;
+
+    /**
+     * Enable MitM (PBX) enrollment
+     * 
+     * If set to true then ZRTP honors the PBX enrollment flag in
+     * Commit packets and calls the appropriate user callback
+     * methods. If the parameter is set to false ZRTP ignores the PBX
+     * enrollment flags.
+     */
+    bool enableMitmEnrollment;
+
+    /**
+     * True if a valid trusted MitM key of the other peer is available, i.e. enrolled.
+     */
+    bool peerIsEnrolled;
+
+    /**
+     * Set to true if the Hello packet contained the M-flag (MitM flag).
+     * We use this later to check some stuff for SAS Relay processing
+     */
+    bool mitmSeen;
+
+    /**
+     * Temporarily store computed pbxSecret, if user accepts enrollment then
+     * it will copied to our ZID record of the PBX (MitM)  
+     */
+    uint8_t* pbxSecretTmp;
+    uint8_t  pbxSecretTmpBuffer[MAX_DIGEST_LENGTH];
+
+    /**
+     * If true then we will set the enrollment flag (E) in the confirm
+     * packets. Set to true if the PBX enrollment service started this ZRTP 
+     * session. Can be set to true only if mitmMode is also true. 
+     */
+    bool enrollmentMode;
+
+    /**
+     * Configuration data which algorithms to use.
+     */
+    ZrtpConfigure configureAlgos;
+    /**
+     * Pre-initialized packets.
+     */
+    ZrtpPacketHello    zrtpHello;
+    ZrtpPacketHelloAck zrtpHelloAck;
+    ZrtpPacketConf2Ack zrtpConf2Ack;
+    ZrtpPacketClearAck zrtpClearAck;
+    ZrtpPacketGoClear  zrtpGoClear;
+    ZrtpPacketError    zrtpError;
+    ZrtpPacketErrorAck zrtpErrorAck;
+    ZrtpPacketDHPart   zrtpDH1;
+    ZrtpPacketDHPart   zrtpDH2;
+    ZrtpPacketCommit   zrtpCommit;
+    ZrtpPacketConfirm  zrtpConfirm1;
+    ZrtpPacketConfirm  zrtpConfirm2;
+    ZrtpPacketPingAck  zrtpPingAck;
+    ZrtpPacketSASrelay zrtpSasRelay;
+    ZrtpPacketRelayAck zrtpRelayAck;
+
+    /**
+     * Random IV data to encrypt the confirm data, 128 bit for AES
+     */
+    uint8_t randomIV[16];
+
+    uint8_t tempMsgBuffer[1024];
+    int32_t lengthOfMsgData;
+
+    /**
+     * Variables to store signature data. Includes the signature type block
+     */
+    const uint8_t* signatureData;       // will be set when needed
+    int32_t  signatureLength;     // overall length in bytes
+
+    /**
+     * Is true if the other peer signaled SAS signature support in its Hello packet.
+     */
+    bool signSasSeen;
+
+    uint32_t peerSSRC;            // peer's SSRC, required to setup PingAck packet
+
+    /**
+     * 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> Force the SAS verify flag to be false at srtpSecretsOn() callback. This gives
+     *      the user interface (UI) the indication to handle the SAS as <b>not verified</b>.
+     *      See implementation note below.</li>
+     * <li> Don't set the SAS verify flag in the <code>Confirm</code> packets, thus the other
+     *      also must report the SAS as <b>not verified</b>.</li>
+     * <li> ignore the <code>SASVerified()</code> function, thus do not set the SAS to verified
+     *      in the ZRTP cache. </li>
+     * <li> Disable the <b>Trusted PBX MitM</b> 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 always display the SAS code if the SAS verify flag is <code>false</code>.
+     * The application shall also use mechanisms to remind the user to compare the SAS code, for
+     * example useing larger fonts, different colours and other display features.
+     */
+    bool paranoidMode;
+
+    /**
+     * Find the best Hash algorithm that is offered in Hello.
+     *
+     * Find the best, that is the strongest, Hash algorithm that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @return
+     *    The Enum that identifies the best offered Hash algortihm. Return
+     *    <code>NumSupportedHashes</code> to signal that no matching Hash algorithm
+     *     was found at all.
+    */
+    AlgorithmEnum* findBestHash(ZrtpPacketHello *hello);
+
+    /**
+     * Find the best symmetric cipher algorithm that is offered in Hello.
+     *
+     * Find the best, that is the strongest, cipher algorithm that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @param pk
+     *    The id of the selected public key algorithm
+     * @return
+     *    The Enum that identifies the best offered Cipher algortihm. Return
+     *    <code>NumSupportedSymCiphers</code> to signal that no matching Cipher algorithm
+     *    was found at all.
+     */
+    AlgorithmEnum* findBestCipher(ZrtpPacketHello *hello,  AlgorithmEnum* pk);
+
+    /**
+     * Find the best Public Key algorithm that is offered in Hello.
+     *
+     * Find the best, that is the strongest, public key algorithm that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @return
+     *    The Enum that identifies the best offered Public Key algortihm. Return
+     *    <code>NumSupportedPubKeys</code> to signal that no matching Public Key algorithm
+     *    was found at all.
+     */
+    AlgorithmEnum* findBestPubkey(ZrtpPacketHello *hello);
+
+    /**
+     * Find the best SAS algorithm that is offered in Hello.
+     *
+     * Find the best, that is the strongest, SAS algorithm that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @return
+     *    The Enum that identifies the best offered SAS algortihm. Return
+     *    <code>NumSupportedSASTypes</code> to signal that no matching SAS algorithm
+     *    was found at all.
+     */
+    AlgorithmEnum* findBestSASType(ZrtpPacketHello* hello);
+
+    /**
+     * Find the best authentication length that is offered in Hello.
+     *
+     * Find the best, that is the strongest, authentication length that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @return
+     *    The Enum that identifies the best offered authentication length. Return
+     *    <code>NumSupportedAuthLenghts</code> to signal that no matching length
+     *    was found at all.
+     */
+    AlgorithmEnum* findBestAuthLen(ZrtpPacketHello* hello);
+
+    /**
+     * Check if MultiStream mode is offered in Hello.
+     *
+     * Find the best, that is the strongest, authentication length that our peer
+     * offers in its Hello packet.
+     *
+     * @param hello
+     *    The Hello packet.
+     * @return
+     *    True if multi stream mode is available, false otherwise.
+     */
+    bool checkMultiStream(ZrtpPacketHello* hello);
+
+    /**
+     * Save the computed MitM secret to the ZID record of the peer
+     */
+    void writeEnrollmentPBX();
+
+    /**
+     * Compute my hvi value according to ZRTP specification.
+     */
+    void computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello);
+
+    void computeSharedSecretSet(ZIDRecord& zidRec);
+
+    void computeSRTPKeys();
+
+    void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
+               uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output);
+
+    void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
+
+    void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
+
+    void generateKeysMultiStream();
+
+    void computePBXSecret();
+
+    void setNegotiatedHash(AlgorithmEnum* hash);
+
+    /*
+     * The following methods are helper functions for ZrtpStateClass.
+     * ZrtpStateClass calls them to prepare packets, send data, report
+     * problems, etc.
+     */
+    /**
+     * Send a ZRTP packet.
+     *
+     * The state engines calls this method to send a packet via the RTP
+     * stack.
+     *
+     * @param packet
+     *    Points to the ZRTP packet.
+     * @return
+     *    zero if sending failed, one if packet was send
+     */
+    int32_t sendPacketZRTP(ZrtpPacketBase *packet);
+
+    /**
+     * Activate a Timer using the host callback.
+     *
+     * @param tm
+     *    The time in milliseconds.
+     * @return
+     *    zero if activation failed, one if timer was activated
+     */
+    int32_t activateTimer(int32_t tm);
+
+    /**
+     * Cancel the active Timer using the host callback.
+     *
+     * @return
+     *    zero if activation failed, one if timer was activated
+     */
+    int32_t cancelTimer();
+
+    /**
+     * Prepare a Hello packet.
+     *
+     * Just take the preinitialized Hello packet and return it. No
+     * further processing required.
+     *
+     * @return
+     *    A pointer to the initialized Hello packet.
+     */
+    ZrtpPacketHello* prepareHello();
+
+    /**
+     * Prepare a HelloAck packet.
+     *
+     * Just take the preinitialized HelloAck packet and return it. No
+     * further processing required.
+     *
+     * @return
+     *    A pointer to the initialized HelloAck packet.
+     */
+    ZrtpPacketHelloAck* prepareHelloAck();
+
+    /**
+     * Prepare a Commit packet.
+     *
+     * We have received a Hello packet from our peer. Check the offers
+     * it makes to us and select the most appropriate. Using the
+     * selected values prepare a Commit packet and return it to protocol
+     * state engine.
+     *
+     * @param hello
+     *    Points to the received Hello packet
+     * @param errMsg
+     *    Points to an integer that can hold a ZRTP error code.
+     * @return
+     *    A pointer to the prepared Commit packet
+     */
+    ZrtpPacketCommit* prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg);
+
+    /**
+     * Prepare a Commit packet for Multi Stream mode.
+     *
+     * Using the selected values prepare a Commit packet and return it to protocol
+     * state engine.
+     *
+     * @param hello
+     *    Points to the received Hello packet
+     * @return
+     *    A pointer to the prepared Commit packet for multi stream mode
+     */
+    ZrtpPacketCommit* prepareCommitMultiStream(ZrtpPacketHello *hello);
+
+    /**
+     * Prepare the DHPart1 packet.
+     *
+     * This method prepares a DHPart1 packet. The input to the method is always
+     * a Commit packet received from the peer. Also we a in the role of the
+     * Responder.
+     *
+     * When we receive a Commit packet we get the selected ciphers, hashes, etc
+     * and cross-check if this is ok. Then we need to initialize a set of DH
+     * keys according to the selected cipher. Using this data we prepare our DHPart1
+     * packet.
+     */
+    ZrtpPacketDHPart* prepareDHPart1(ZrtpPacketCommit *commit, uint32_t* errMsg);
+
+    /**
+     * Prepare the DHPart2 packet.
+     *
+     * This method prepares a DHPart2 packet. The input to the method is always
+     * a DHPart1 packet received from the peer. Our peer sends the DH1Part as
+     * response to our Commit packet. Thus we are in the role of the
+     * Initiator.
+     *
+     */
+    ZrtpPacketDHPart* prepareDHPart2(ZrtpPacketDHPart* dhPart1, uint32_t* errMsg);
+
+    /**
+     * Prepare the Confirm1 packet.
+     *
+     * This method prepare the Confirm1 packet. The input to this method is the
+     * DHPart2 packect received from our peer. The peer sends the DHPart2 packet
+     * as response of our DHPart1. Here we are in the role of the Responder
+     *
+     */
+    ZrtpPacketConfirm* prepareConfirm1(ZrtpPacketDHPart* dhPart2, uint32_t* errMsg);
+
+    /**
+     * Prepare the Confirm1 packet in multi stream mode.
+     *
+     * This method prepares the Confirm1 packet. The state engine call this method
+     * if multi stream mode is selected and a Commit packet was received. The input to
+     * this method is the Commit.
+     * Here we are in the role of the Responder
+     *
+     */
+    ZrtpPacketConfirm* prepareConfirm1MultiStream(ZrtpPacketCommit* commit, uint32_t* errMsg);
+
+    /**
+     * Prepare the Confirm2 packet.
+     *
+     * This method prepare the Confirm2 packet. The input to this method is the
+     * Confirm1 packet received from our peer. The peer sends the Confirm1 packet
+     * as response of our DHPart2. Here we are in the role of the Initiator
+     */
+    ZrtpPacketConfirm* prepareConfirm2(ZrtpPacketConfirm* confirm1, uint32_t* errMsg);
+
+    /**
+     * Prepare the Confirm2 packet in multi stream mode.
+     *
+     * This method prepares the Confirm2 packet. The state engine call this method if
+     * multi stream mode is active and in state CommitSent. The input to this method is
+     * the Confirm1 packet received from our peer. The peer sends the Confirm1 packet
+     * as response of our Commit packet in multi stream mode.
+     * Here we are in the role of the Initiator
+     */
+    ZrtpPacketConfirm* prepareConfirm2MultiStream(ZrtpPacketConfirm* confirm1, uint32_t* errMsg);
+
+    /**
+     * Prepare the Conf2Ack packet.
+     *
+     * This method prepare the Conf2Ack packet. The input to this method is the
+     * Confirm2 packet received from our peer. The peer sends the Confirm2 packet
+     * as response of our Confirm1. Here we are in the role of the Initiator
+     */
+    ZrtpPacketConf2Ack* prepareConf2Ack(ZrtpPacketConfirm* confirm2, uint32_t* errMsg);
+
+    /**
+     * Prepare the ErrorAck packet.
+     *
+     * This method prepares the ErrorAck packet. The input to this method is the
+     * Error packet received from the peer.
+     */
+    ZrtpPacketErrorAck* prepareErrorAck(ZrtpPacketError* epkt);
+
+    /**
+     * Prepare the Error packet.
+     *
+     * This method prepares the Error packet. The input to this method is the
+     * error code to be included into the message.
+     */
+    ZrtpPacketError* prepareError(uint32_t errMsg);
+
+    /**
+     * Prepare a ClearAck packet.
+     *
+     * This method checks if the GoClear message is valid. If yes then switch
+     * off SRTP processing, stop sending of RTP packets (pause transmit) and
+     * inform the user about the fact. Only if user confirms the GoClear message
+     * normal RTP processing is resumed.
+     *
+     * @return
+     *     NULL if GoClear could not be authenticated, a ClearAck packet
+     *     otherwise.
+     */
+    ZrtpPacketClearAck* prepareClearAck(ZrtpPacketGoClear* gpkt);
+
+    /**
+     * Prepare the ErrorAck packet.
+     *
+     * This method prepares the ErrorAck packet. The input to this method is the
+     * Error packet received from the peer.
+     */
+    ZrtpPacketPingAck* preparePingAck(ZrtpPacketPing* ppkt);
+
+    /**
+     * Prepare the RelayAck packet.
+     *
+     * This method prepares the RelayAck packet. The input to this method is the
+     * SASrelay packet received from the peer.
+     */
+    ZrtpPacketRelayAck* prepareRelayAck(ZrtpPacketSASrelay* srly, uint32_t* errMsg);
+    
+    /**
+     * Prepare a GoClearAck packet w/o HMAC
+     *
+     * Prepare a GoCLear packet without a HMAC but with a short error message.
+     * This type of GoClear is used if something went wrong during the ZRTP
+     * negotiation phase.
+     *
+     * @return
+     *     A goClear packet without HMAC
+     */
+    ZrtpPacketGoClear* prepareGoClear(uint32_t errMsg = 0);
+
+    /**
+     * Compare the hvi values.
+     *
+     * Compare a received Commit packet with our Commit packet and returns
+     * which Commit packt is "more important". See chapter 5.2 to get further
+     * information how to compare Commit packets.
+     *
+     * @param commit
+     *    Pointer to the peer's commit packet we just received.
+     * @return
+     *    <0 if our Commit packet is "less important"
+     *    >0 if our Commit is "more important"
+     *     0 shouldn't happen because we compare crypto hashes
+     */
+    int32_t compareCommit(ZrtpPacketCommit *commit);
+
+    /**
+     * Verify the H2 hash image.
+     *
+     * Verifies the H2 hash contained in a received commit message.
+     * This functions just verifies H2 but does not store it.
+     *
+     * @param commit
+     *    Pointer to the peer's commit packet we just received.
+     * @return
+     *    true if H2 is ok and verified
+     *    false if H2 could not be verified
+     */
+    bool verifyH2(ZrtpPacketCommit *commit);
+
+    /**
+     * Send information messages to the hosting environment.
+     *
+     * The ZRTP implementation uses this method to send information messages
+     * to the host. Along with the message ZRTP provides a severity indicator
+     * that defines: Info, Warning, Error, Alert. Refer to the MessageSeverity
+     * enum in the ZrtpCallback class.
+     *
+     * @param severity
+     *     This defines the message's severity
+     * @param subCode
+     *     The subcode identifying the reason.
+     * @see ZrtpCodes#MessageSeverity
+     */
+    void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
+
+    /**
+     * ZRTP state engine calls this if the negotiation failed.
+     *
+     * ZRTP calls this method in case ZRTP negotiation failed. The parameters
+     * show the severity as well as some explanatory text.
+     *
+     * @param severity
+     *     This defines the message's severity
+     * @param subCode
+     *     The subcode identifying the reason.
+     * @see ZrtpCodes#MessageSeverity
+     */
+    void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
+
+    /**
+     * ZRTP state engine calls this method if the other side does not support ZRTP.
+     *
+     * If the other side does not answer the ZRTP <em>Hello</em> packets then
+     * ZRTP calls this method,
+     *
+     */
+    void zrtpNotSuppOther();
+
+    /**
+     * Signal SRTP secrets are ready.
+     *
+     * This method calls a callback method to inform the host that the SRTP
+     * secrets are ready.
+     *
+     * @param part
+     *    Defines for which part (sender or receiver) to switch on security
+     * @return
+     *    Returns false if something went wrong during initialization of SRTP
+     *    context. Propagate error back to state engine.
+     */
+    bool srtpSecretsReady(EnableSecurity part);
+
+    /**
+     * Switch off SRTP secrets.
+     *
+     * This method calls a callback method to inform the host that the SRTP
+     * secrets shall be cleared.
+     *
+     * @param part
+     *    Defines for which part (sender or receiver) to clear
+     */
+    void srtpSecretsOff(EnableSecurity part);
+
+    /**
+     * ZRTP state engine calls these methods to enter or leave its
+     * synchronization mutex.
+     */
+    void synchEnter();
+
+    void synchLeave();
+
+    /**
+     * Helper function to store ZRTP message data in a temporary buffer
+     *
+     * This functions first clears the temporary buffer, then stores
+     * the packet's data to it. We use this to check the packet's HMAC
+     * after we received the HMAC key in to following packet.
+     *
+     * @param data
+     *    Pointer to the packet's ZRTP message
+    */
+     void storeMsgTemp(ZrtpPacketBase* pkt);
+
+     /**
+      * Helper function to check a ZRTP message HMAC
+      *
+      * This function gets a HMAC key and uses it to compute a HMAC
+      * with this key and the stored data of a previous received ZRTP
+      * message. It compares the computed HMAC and the HMAC stored in
+      * the received message and returns the result.
+      *
+      * @param key
+      *    Pointer to the HMAC key.
+      * @return
+      *    Returns true if the computed HMAC and the stored HMAC match,
+      *    false otherwise.
+      */
+     bool checkMsgHmac(uint8_t* key);
+
+     /**
+      * Set the client ID for ZRTP Hello message.
+      *
+      * The user of ZRTP must set its id to identify itself in the
+      * ZRTP HELLO message. The maximum length is 16 characters. Shorter
+      * id string are allowed, they will be filled with blanks. A longer id
+      * is truncated to 16 characters.
+      *
+      * The identifier is set in the Hello packet of ZRTP. Thus only after
+      * setting the identifier ZRTP can compute the HMAC and the final
+      * helloHash.
+      *
+      * @param id
+      *     The client's id
+      */
+     void setClientId(std::string id);
+};
+
+/**
+ * @}
+ */
+#endif // ZRTP
+