* #27232: jni: added pjproject checkout as regular git content

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/third_party/milenage/milenage.c b/jni/pjproject-android/third_party/milenage/milenage.c
new file mode 100644
index 0000000..66dae9b
--- /dev/null
+++ b/jni/pjproject-android/third_party/milenage/milenage.c
@@ -0,0 +1,284 @@
+/*-------------------------------------------------------------------
+ *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*
+ *-------------------------------------------------------------------
+ *
+ *  A sample implementation of the example 3GPP authentication and
+ *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is
+ *  a byte-oriented implementation of the functions, and of the block
+ *  cipher kernel function Rijndael.
+ *
+ *  This has been coded for clarity, not necessarily for efficiency.
+ *
+ *  The functions f2, f3, f4 and f5 share the same inputs and have
+ *  been coded together as a single function.  f1, f1* and f5* are
+ *  all coded separately.
+ *
+ *-----------------------------------------------------------------*/
+
+#include "milenage.h"
+#include "rijndael.h"
+
+/*--------------------------- prototypes --------------------------*/
+
+
+
+/*-------------------------------------------------------------------
+ *                            Algorithm f1
+ *-------------------------------------------------------------------
+ *
+ *  Computes network authentication code MAC-A from key K, random
+ *  challenge RAND, sequence number SQN and authentication management
+ *  field AMF.
+ *
+ *-----------------------------------------------------------------*/
+
+void f1    ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], 
+             u8 mac_a[8], u8 op[16] )
+{
+  u8 op_c[16];
+  u8 temp[16];
+  u8 in1[16];
+  u8 out1[16];
+  u8 rijndaelInput[16];
+  u8 i;
+
+  RijndaelKeySchedule( k );
+
+  ComputeOPc( op_c, op );
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] = rand[i] ^ op_c[i];
+  RijndaelEncrypt( rijndaelInput, temp );
+
+  for (i=0; i<6; i++)
+  {
+    in1[i]    = sqn[i];
+    in1[i+8]  = sqn[i];
+  }
+  for (i=0; i<2; i++)
+  {
+    in1[i+6]  = amf[i];
+    in1[i+14] = amf[i];
+  }
+
+  /* XOR op_c and in1, rotate by r1=64, and XOR *
+   * on the constant c1 (which is all zeroes)   */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
+
+  /* XOR on the value temp computed before */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] ^= temp[i];
+  
+  RijndaelEncrypt( rijndaelInput, out1 );
+  for (i=0; i<16; i++)
+    out1[i] ^= op_c[i];
+
+  for (i=0; i<8; i++)
+    mac_a[i] = out1[i];
+
+  return;
+} /* end of function f1 */
+
+
+  
+/*-------------------------------------------------------------------
+ *                            Algorithms f2-f5
+ *-------------------------------------------------------------------
+ *
+ *  Takes key K and random challenge RAND, and returns response RES,
+ *  confidentiality key CK, integrity key IK and anonymity key AK.
+ *
+ *-----------------------------------------------------------------*/
+
+void f2345 ( u8 k[16], u8 rand[16],
+             u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] )
+{
+  u8 op_c[16];
+  u8 temp[16];
+  u8 out[16];
+  u8 rijndaelInput[16];
+  u8 i;
+
+  RijndaelKeySchedule( k );
+
+  ComputeOPc( op_c, op );
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] = rand[i] ^ op_c[i];
+  RijndaelEncrypt( rijndaelInput, temp );
+
+  /* To obtain output block OUT2: XOR OPc and TEMP,    *
+   * rotate by r2=0, and XOR on the constant c2 (which *
+   * is all zeroes except that the last bit is 1).     */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] = temp[i] ^ op_c[i];
+  rijndaelInput[15] ^= 1;
+
+  RijndaelEncrypt( rijndaelInput, out );
+  for (i=0; i<16; i++)
+    out[i] ^= op_c[i];
+
+  for (i=0; i<8; i++)
+    res[i] = out[i+8];
+  for (i=0; i<6; i++)
+    ak[i]  = out[i];
+
+  /* To obtain output block OUT3: XOR OPc and TEMP,        *
+   * rotate by r3=32, and XOR on the constant c3 (which    *
+   * is all zeroes except that the next to last bit is 1). */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i];
+  rijndaelInput[15] ^= 2;
+
+  RijndaelEncrypt( rijndaelInput, out );
+  for (i=0; i<16; i++)
+    out[i] ^= op_c[i];
+
+  for (i=0; i<16; i++)
+    ck[i] = out[i];
+
+  /* To obtain output block OUT4: XOR OPc and TEMP,         *
+   * rotate by r4=64, and XOR on the constant c4 (which     *
+   * is all zeroes except that the 2nd from last bit is 1). */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i];
+  rijndaelInput[15] ^= 4;
+
+  RijndaelEncrypt( rijndaelInput, out );
+  for (i=0; i<16; i++)
+    out[i] ^= op_c[i];
+
+  for (i=0; i<16; i++)
+    ik[i] = out[i];
+
+  return;
+} /* end of function f2345 */
+
+  
+/*-------------------------------------------------------------------
+ *                            Algorithm f1*
+ *-------------------------------------------------------------------
+ *
+ *  Computes resynch authentication code MAC-S from key K, random
+ *  challenge RAND, sequence number SQN and authentication management
+ *  field AMF.
+ *
+ *-----------------------------------------------------------------*/
+
+void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], 
+             u8 mac_s[8], u8 op[16] )
+{
+  u8 op_c[16];
+  u8 temp[16];
+  u8 in1[16];
+  u8 out1[16];
+  u8 rijndaelInput[16];
+  u8 i;
+
+  RijndaelKeySchedule( k );
+
+  ComputeOPc( op_c, op );
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] = rand[i] ^ op_c[i];
+  RijndaelEncrypt( rijndaelInput, temp );
+
+  for (i=0; i<6; i++)
+  {
+    in1[i]    = sqn[i];
+    in1[i+8]  = sqn[i];
+  }
+  for (i=0; i<2; i++)
+  {
+    in1[i+6]  = amf[i];
+    in1[i+14] = amf[i];
+  }
+
+  /* XOR op_c and in1, rotate by r1=64, and XOR *
+   * on the constant c1 (which is all zeroes)   */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
+
+  /* XOR on the value temp computed before */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] ^= temp[i];
+  
+  RijndaelEncrypt( rijndaelInput, out1 );
+  for (i=0; i<16; i++)
+    out1[i] ^= op_c[i];
+
+  for (i=0; i<8; i++)
+    mac_s[i] = out1[i+8];
+
+  return;
+} /* end of function f1star */
+
+  
+/*-------------------------------------------------------------------
+ *                            Algorithm f5*
+ *-------------------------------------------------------------------
+ *
+ *  Takes key K and random challenge RAND, and returns resynch
+ *  anonymity key AK.
+ *
+ *-----------------------------------------------------------------*/
+
+void f5star( u8 k[16], u8 rand[16],
+             u8 ak[6], u8 op[16] )
+{
+  u8 op_c[16];
+  u8 temp[16];
+  u8 out[16];
+  u8 rijndaelInput[16];
+  u8 i;
+
+  RijndaelKeySchedule( k );
+
+  ComputeOPc( op_c, op );
+
+  for (i=0; i<16; i++)
+    rijndaelInput[i] = rand[i] ^ op_c[i];
+  RijndaelEncrypt( rijndaelInput, temp );
+
+  /* To obtain output block OUT5: XOR OPc and TEMP,         *
+   * rotate by r5=96, and XOR on the constant c5 (which     *
+   * is all zeroes except that the 3rd from last bit is 1). */
+
+  for (i=0; i<16; i++)
+    rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i];
+  rijndaelInput[15] ^= 8;
+
+  RijndaelEncrypt( rijndaelInput, out );
+  for (i=0; i<16; i++)
+    out[i] ^= op_c[i];
+
+  for (i=0; i<6; i++)
+    ak[i] = out[i];
+
+  return;
+} /* end of function f5star */
+
+  
+/*-------------------------------------------------------------------
+ *  Function to compute OPc from OP and K.  Assumes key schedule has
+    already been performed.
+ *-----------------------------------------------------------------*/
+
+void ComputeOPc( u8 op_c[16], u8 op[16] )
+{
+  u8 i;
+  
+  RijndaelEncrypt( op, op_c );
+  for (i=0; i<16; i++)
+    op_c[i] ^= op[i];
+
+  return;
+} /* end of function ComputeOPc */