diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2015-04-13 09:21:39 +0200 |
---|---|---|
committer | Michal Kubecek <mkubecek@suse.cz> | 2015-04-13 09:21:39 +0200 |
commit | e2bc6f4153813cc570ae814c8ddb74628009b488 (patch) | |
tree | a40b171be1d859c2232ccc94f758010f9ae54d3c /src/parser/milenage.cpp | |
download | twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.gz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.lz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.tar.xz twinkle-e2bc6f4153813cc570ae814c8ddb74628009b488.zip |
initial checkin
Check in contents of upstream 1.4.2 tarball, exclude generated files.
Diffstat (limited to 'src/parser/milenage.cpp')
-rw-r--r-- | src/parser/milenage.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/parser/milenage.cpp b/src/parser/milenage.cpp new file mode 100644 index 0000000..66dae9b --- /dev/null +++ b/src/parser/milenage.cpp @@ -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 */ |