MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen
Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/common/f9.c b/src/common/f9.c
new file mode 100644
index 0000000..c001641
--- /dev/null
+++ b/src/common/f9.c
@@ -0,0 +1,210 @@
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "f9.h"
+
+/* The code has been referred from
+ * 1.https://www.gsma.com/aboutus/wp-content/uploads/2014/12/uea2uia2d1v21.pdf
+ * 2.https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf
+ *
+ */
+
+
+/* MUL64x.
+ * Input V: a 64-bit input.
+ * Input c: a 64-bit input.
+ * Output : a 64-bit output.
+ * A 64-bit memory is allocated which is to be freed by the calling
+ * function.
+ * See section 4.3.2
+ * (https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf)
+ * for more details.
+ */
+
+
+u64 MUL64x(u64 V, u64 c)
+{
+ if ( V & 0x8000000000000000 )
+ return (V << 1) ^ c;
+ else
+ return V << 1;
+}
+
+/* MUL64xPOW.
+ * Input V: a 64-bit input.
+ * Input i: a positive integer.
+ * Input c: a 64-bit input.
+ * Output : a 64-bit output.
+ * A 64-bit memory is allocated which is to be freed by the calling
+ function.
+ * See section 4.3.3
+ * (https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf)
+ * for more details.
+ */
+
+u64 MUL64xPOW(u64 V, u8 i, u64 c)
+{
+ if ( i == 0)
+ return V;
+ else
+ return MUL64x( MUL64xPOW(V,i-1,c) , c);
+
+ return V;
+}
+
+/* MUL64.
+ * Input V: a 64-bit input.
+ * Input P: a 64-bit input.
+ * Input c: a 64-bit input.
+ * Output : a 64-bit output.
+ * A 64-bit memory is allocated which is to be freed by the calling
+ * function.
+ * See section 4.3.4
+ * (https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf)
+ * for more details.
+ */
+
+
+u64 MUL64(u64 V, u64 P, u64 c)
+{
+ u64 result = 0;
+ int i = 0;
+ for ( i=0; i<64; i++)
+ {
+ if( ( P>>i ) & 0x1 )
+ result ^= MUL64xPOW(V,i,c);
+ }
+
+ return result;
+}
+
+
+/* mask8bit.
+ * Input n: an integer in 1-7.
+ * Output : an 8 bit mask.
+ * Prepares an 8 bit mask with required number of 1 bits on the MSB side.
+ */
+
+u8 mask8bit(int n)
+{
+ return 0xFF ^ ((1<<(8-n)) - 1);
+}
+
+/* f9.
+ * Input key: 128 bit Integrity Key.
+ * Input count:32-bit Count, Frame dependent input.
+ * Input fresh: 32-bit Random number.
+ * Input dir:1 bit, direction of transmission (in the LSB).
+ * Input data: length number of bits, input bit stream.
+ * Input length: 64 bit Length, i.e., the number of bits to be MAC'd.
+ * Output : 32 bit block used as MAC
+ * Generates 32-bit MAC using UIA2 algorithm as defined in Section 4.
+ */
+
+u8* f9( u8* key, u32 count, u32 fresh, u32 dir, u8 *data, u64 length)
+{
+ u32 K[4],IV[4], z[5];
+ u32 i=0,D;
+ static u8 MAC_I[4] = {0,0,0,0}; /* static memory for the result */
+ u64 EVAL;
+ u64 V;
+ u64 P;
+ u64 Q;
+ u64 c;
+ u64 M_D_2;
+ int rem_bits = 0;
+
+ /* Load the Integrity Key for SNOW3G initialization as in section 4.4. */
+
+ for (i=0; i<4; i++)
+ K[3-i] = (key[4*i] << 24) ^ (key[4*i+1] << 16) ^ (key[4*i+2] << 8) ^
+ (key[4*i+3]);
+
+
+ /* Prepare the Initialization Vector (IV) for SNOW3G initialization as in
+ section 4.4 of
+ (https://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.pdf).
+ */
+
+ IV[3] = count;
+ IV[2] = fresh;
+ IV[1] = count ^ ( dir << 31 ) ;
+ IV[0] = fresh ^ (dir << 15);
+ z[0] = z[1] = z[2] = z[3] = z[4] = 0;
+
+ /* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */
+
+ Initialize(K,IV);
+ GenerateKeystream(5,z);
+
+ P = (u64)z[0] << 32 | (u64)z[1];
+ Q = (u64)z[2] << 32 | (u64)z[3];
+
+ /* Calculation */
+
+ if ((length % 64) == 0)
+ D = (length>>6) + 1;
+ else
+ D = (length>>6) + 2;
+
+ EVAL = 0;
+ c = 0x1b;
+
+ /* for 0 <= i <= D-3 */
+
+ for (i=0;i<D-2;i++)
+ {
+ V = EVAL ^ ( (u64)data[8*i ]<<56 | (u64)data[8*i+1]<<48 |
+ (u64)data[8*i+2]<<40 | (u64)data[8*i+3]<<32 |
+ (u64)data[8*i+4]<<24 | (u64)data[8*i+5]<<16 |
+ (u64)data[8*i+6]<< 8 | (u64)data[8*i+7] );
+
+ EVAL = MUL64(V,P,c);
+ }
+
+ /* for D-2 */
+
+ rem_bits = length % 64;
+ if (rem_bits == 0)
+ rem_bits = 64;
+
+ M_D_2 = 0;
+ i = 0;
+
+ while (rem_bits > 7)
+ {
+ M_D_2 |= (u64)data[8*(D-2)+i] << (8*(7-i));
+ rem_bits -= 8;
+ i++;
+ }
+
+ if (rem_bits > 0)
+ M_D_2 |= (u64)(data[8*(D-2)+i] & mask8bit(rem_bits)) << (8*(7-i));
+
+ V = EVAL ^ M_D_2;
+ EVAL = MUL64(V,P,c);
+
+ /* for D-1 */
+
+ EVAL ^= length;
+
+ /* Multiply by Q */
+
+ EVAL = MUL64(EVAL,Q,c);
+
+ for (i=0; i<4; i++) {
+
+ /* GSLab-Intel modification to the specs reference code
+ * https://www.gsma.com/aboutus/wp-content/uploads/2014/12/uea2uia2d1v21.pdf
+ * which forgot to XOR z[5]
+ */
+
+ MAC_I[i] = ((EVAL >> (8 * (7-i))) ^ (z[4] >> (8 * (3-i)))) & 0xff;
+
+ }
+ return MAC_I;
+
+}
+/* End of f9.c */
+/*------------------------------------------------------------------------*/