* #35924 (zrtp): switch to libzrtpcpp
diff --git a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c b/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
new file mode 100755
index 0000000..241b956
--- /dev/null
+++ b/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
@@ -0,0 +1,94 @@
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "twofish.h"
+
+void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in, 
+			    Twofish_Byte* out, size_t len,
+			    Twofish_Byte* ivec, int32_t *num)
+{
+  uint32_t n;
+
+  n = *num;
+
+  do {
+    while (n && len) {
+      *(out++) = ivec[n] ^= *(in++);
+      --len;
+      n = (n+1) % 16;
+    }
+    while (len>=16) {
+      Twofish_encrypt(keyCtx, ivec, ivec);
+      for (n=0; n<16; n+=sizeof(size_t)) {
+
+/*
+ * Some GCC version(s) of Android's NDK produce code that leads to a crash (SIGBUS). The
+ * offending line if the line that produces the output by xor'ing the ivec. Somehow the
+ * compiler/optimizer seems to incorrectly setup the pointers. Adding a call to an
+ * external function that uses the pointer disabled or modifies this optimzing
+ * behaviour. This debug functions as such does nothing, it just disables some
+ * optimization. Don't use a local (static) function - the compiler sees that it does
+ * nothing and optimizes again :-) .
+ */
+#ifdef ANDROID
+          Two_debugDummy(in, out, ivec);
+#endif
+          *(size_t*)(out+n) = *(size_t*)(ivec+n) ^= *(size_t*)(in+n);;
+      }
+      len -= 16;
+      out += 16;
+      in  += 16;
+    }
+    n = 0;
+    if (len) {
+      Twofish_encrypt(keyCtx, ivec, ivec);
+      while (len--) {
+          out[n] = ivec[n] ^= in[n];
+          ++n;
+      }
+    }
+    *num = n;
+    return;
+  } while (0);
+}
+
+
+void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in, 
+			    Twofish_Byte* out, size_t len,
+			    Twofish_Byte* ivec, int32_t *num)
+{
+  uint32_t n;
+
+  n = *num;
+
+  do {
+    while (n && len) {
+      unsigned char c;
+      *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
+      --len;
+      n = (n+1) % 16;
+    }
+    while (len>=16) {
+      Twofish_encrypt(keyCtx, ivec, ivec);
+      for (n=0; n<16; n+=sizeof(size_t)) {
+	size_t t = *(size_t*)(in+n);
+	*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
+	*(size_t*)(ivec+n) = t;
+      }
+      len -= 16;
+      out += 16;
+      in  += 16;
+    }
+    n = 0;
+    if (len) {
+      Twofish_encrypt(keyCtx, ivec, ivec);
+      while (len--) {
+	unsigned char c;
+	out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
+	++n;
+      }
+    }
+    *num = n;
+    return;
+  } while (0);
+}