* #35924 (zrtp): switch to libzrtpcpp
diff --git a/jni/libzrtp/sources/srtp/SrtpHandler.cpp b/jni/libzrtp/sources/srtp/SrtpHandler.cpp
new file mode 100644
index 0000000..621e25a
--- /dev/null
+++ b/jni/libzrtp/sources/srtp/SrtpHandler.cpp
@@ -0,0 +1,261 @@
+/*
+  Copyright (C) 2012 Werner Dittmann
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+/*
+ * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <common/osSpecifics.h>
+
+#include <SrtpHandler.h>
+#include <CryptoContext.h>
+#include <CryptoContextCtrl.h>
+
+#define RTP_HEADER_LENGTH 12
+
+bool SrtpHandler::decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen)
+{
+    int offset;
+    uint16_t *pus;
+    uint32_t *pui;
+
+    /* Assume RTP header at the start of buffer. */
+
+    if ((*buffer & 0xC0) != 0x80) {         // check version bits
+        return false;
+    }
+    if (length < RTP_HEADER_LENGTH)
+        return false;
+
+    /* Get some handy pointers */
+    pus = (uint16_t*)buffer;
+    pui = (uint32_t*)buffer;
+
+    uint16_t tmp16 = pus[1];                    // get seq number
+    *seq = zrtpNtohs(tmp16);                        // and return in host oder
+
+    uint32_t tmp32 = pui[2];                    // get SSRC
+    *ssrc = zrtpNtohl(tmp32);                       // and return in host order
+
+    /* Payload is located right after header plus CSRC */
+    int32_t numCC = buffer[0] & 0x0f;           // lower 4 bits in first byte is num of contrib SSRC
+    offset = RTP_HEADER_LENGTH + (numCC * sizeof(uint32_t));
+
+    // Sanity check
+    if (offset > length)
+        return false;
+
+    /* Adjust payload offset if RTP extension is used. */
+    if ((*buffer & 0x10) == 0x10) {             // packet contains RTP extension
+        pus = (uint16_t*)(buffer + offset);     // pus points to extension as 16bit pointer
+        tmp16 = pus[1];                         // the second 16 bit word is the length
+        tmp16 = zrtpNtohs(tmp16);                   // to host order
+        offset += (tmp16 + 1) * sizeof(uint32_t);
+    }
+    /* Sanity check */
+    if (offset > length)
+        return false;
+
+    /* Set payload and payload length. */
+    *payload = buffer + offset;
+    *payloadlen = length - offset;
+
+    return true;
+}
+
+bool SrtpHandler::protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
+{
+    uint8_t* payload = NULL;
+    int32_t payloadlen = 0;
+    uint16_t seqnum;
+    uint32_t ssrc;
+
+
+    if (pcc == NULL) {
+        return false;
+    }
+    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
+        return false;
+
+    /* Encrypt the packet */
+    uint64_t index = ((uint64_t)pcc->getRoc() << 16) | (uint64_t)seqnum;
+
+    pcc->srtpEncrypt(buffer, payload, payloadlen, index, ssrc);
+
+    // NO MKI support yet - here we assume MKI is zero. To build in MKI
+    // take MKI length into account when storing the authentication tag.
+
+    /* Compute MAC and store at end of RTP packet data */
+    if (pcc->getTagLength() > 0) {
+        pcc->srtpAuthenticate(buffer, length, pcc->getRoc(), buffer+length);
+    }
+    *newLength = length + pcc->getTagLength();
+
+    /* Update the ROC if necessary */
+    if (seqnum == 0xFFFF ) {
+        pcc->setRoc(pcc->getRoc() + 1);
+    }
+    return true;
+}
+
+int32_t SrtpHandler::unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
+{
+    uint8_t* payload = NULL;
+    int32_t payloadlen = 0;
+    uint16_t seqnum;
+    uint32_t ssrc;
+
+    if (pcc == NULL) {
+        return 0;
+    }
+
+    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
+        return 0;
+    /*
+     * This is the setting of the packet data when we come to this point:
+     *
+     * length:      complete length of received data
+     * buffer:      points to data as received from network
+     * payloadlen:  length of data excluding hdrSize and padding
+     *
+     * Because this is an SRTP packet we need to adjust some values here.
+     * The SRTP MKI and authentication data is always at the end of a
+     * packet. Thus compute the position of this data.
+     */
+    uint32_t srtpDataIndex = length - (pcc->getTagLength() + pcc->getMkiLength());
+
+    // Compute new length
+    length -= pcc->getTagLength() + pcc->getMkiLength();
+    *newLength = length;
+
+    // recompute payloadlen by subtracting SRTP data
+    payloadlen -= pcc->getTagLength() + pcc->getMkiLength();
+
+    // MKI is unused, so just skip it
+    // const uint8* mki = buffer + srtpDataIndex;
+    uint8_t* tag = buffer + srtpDataIndex + pcc->getMkiLength();
+
+    /* Replay control */
+    if (!pcc->checkReplay(seqnum)) {
+        return -2;
+    }
+    /* Guess the index */
+    uint64_t guessedIndex = pcc->guessIndex(seqnum);
+
+    if (pcc->getTagLength() > 0) {
+        uint32_t guessedRoc = guessedIndex >> 16;
+        uint8_t mac[20];
+
+        pcc->srtpAuthenticate(buffer, (uint32_t)length, guessedRoc, mac);
+        if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
+            return -1;
+        }
+    }
+    /* Decrypt the content */
+    pcc->srtpEncrypt(buffer, payload, payloadlen, guessedIndex, ssrc);
+
+    /* Update the Crypto-context */
+    pcc->update(seqnum);
+
+    return 1;
+}
+
+
+bool SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
+{
+
+    if (pcc == NULL) {
+        return false;
+    }
+    /* Encrypt the packet */
+    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
+    ssrc = zrtpNtohl(ssrc);
+
+    uint32_t encIndex = pcc->getSrtcpIndex();
+    pcc->srtcpEncrypt(buffer + 8, length - 8, encIndex, ssrc);
+
+    encIndex |= 0x80000000;                                     // set the E flag
+
+    // Fill SRTCP index as last word
+    uint32_t* ip = reinterpret_cast<uint32_t*>(buffer+length);
+    *ip = zrtpHtonl(encIndex);
+
+    // NO MKI support yet - here we assume MKI is zero. To build in MKI
+    // take MKI length into account when storing the authentication tag.
+
+    // Compute MAC and store in packet after the SRTCP index field
+    pcc->srtcpAuthenticate(buffer, length, encIndex, buffer + length + sizeof(uint32_t));
+
+    encIndex++;
+    encIndex &= ~0x80000000;                                // clear the E-flag and modulo 2^31
+    pcc->setSrtcpIndex(encIndex);
+    *newLength = length + pcc->getTagLength() + sizeof(uint32_t);
+
+    return true;
+}
+
+int32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
+{
+
+    if (pcc == NULL) {
+        return 0;
+    }
+
+    // Compute the total length of the payload
+    int32_t payloadLen = length - (pcc->getTagLength() + pcc->getMkiLength() + 4);
+    *newLength = payloadLen;
+
+    // point to the SRTCP index field just after the real payload
+    const uint32_t* index = reinterpret_cast<uint32_t*>(buffer + payloadLen);
+
+    uint32_t encIndex = zrtpNtohl(*index);
+    uint32_t remoteIndex = encIndex & ~0x80000000;    // get index without Encryption flag
+
+    if (!pcc->checkReplay(remoteIndex)) {
+       return -2;
+    }
+
+    uint8_t mac[20];
+
+    // Now get a pointer to the authentication tag field
+    const uint8_t* tag = buffer + (length - pcc->getTagLength());
+
+    // Authenticate includes the index, but not MKI and not (obviously) the tag itself
+    pcc->srtcpAuthenticate(buffer, payloadLen, encIndex, mac);
+    if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
+        return -1;
+    }
+
+    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
+    ssrc = zrtpNtohl(ssrc);
+
+    // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)
+    if (encIndex & 0x80000000)
+        pcc->srtcpEncrypt(buffer + 8, payloadLen - 8, remoteIndex, ssrc);
+
+    // Update the Crypto-context
+    pcc->update(remoteIndex);
+
+    return 1;
+}
+