Parent Directory
|
Revision Log
Package all media, etc. needed for Public demo system into one tree
1 /*------------------------------------------------------------------- 2 * Example algorithms f1, f1*, f2, f3, f4, f5, f5* 3 *------------------------------------------------------------------- 4 * 5 * A sample implementation of the example 3GPP authentication and 6 * key agreement functions f1, f1*, f2, f3, f4, f5 and f5*. This is 7 * a byte-oriented implementation of the functions, and of the block 8 * cipher kernel function Rijndael. 9 * 10 * This has been coded for clarity, not necessarily for efficiency. 11 * 12 * The functions f2, f3, f4 and f5 share the same inputs and have 13 * been coded together as a single function. f1, f1* and f5* are 14 * all coded separately. 15 * 16 *-----------------------------------------------------------------*/ 17 18 #include "milenage.h" 19 #include "rijndael.h" 20 21 /*--------------------------- prototypes --------------------------*/ 22 23 24 25 /*------------------------------------------------------------------- 26 * Algorithm f1 27 *------------------------------------------------------------------- 28 * 29 * Computes network authentication code MAC-A from key K, random 30 * challenge RAND, sequence number SQN and authentication management 31 * field AMF. 32 * 33 *-----------------------------------------------------------------*/ 34 35 void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], 36 u8 mac_a[8], u8 op[16] ) 37 { 38 u8 op_c[16]; 39 u8 temp[16]; 40 u8 in1[16]; 41 u8 out1[16]; 42 u8 rijndaelInput[16]; 43 u8 i; 44 45 RijndaelKeySchedule( k ); 46 47 ComputeOPc( op_c, op ); 48 49 for (i=0; i<16; i++) 50 rijndaelInput[i] = rand[i] ^ op_c[i]; 51 RijndaelEncrypt( rijndaelInput, temp ); 52 53 for (i=0; i<6; i++) 54 { 55 in1[i] = sqn[i]; 56 in1[i+8] = sqn[i]; 57 } 58 for (i=0; i<2; i++) 59 { 60 in1[i+6] = amf[i]; 61 in1[i+14] = amf[i]; 62 } 63 64 /* XOR op_c and in1, rotate by r1=64, and XOR * 65 * on the constant c1 (which is all zeroes) */ 66 67 for (i=0; i<16; i++) 68 rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; 69 70 /* XOR on the value temp computed before */ 71 72 for (i=0; i<16; i++) 73 rijndaelInput[i] ^= temp[i]; 74 75 RijndaelEncrypt( rijndaelInput, out1 ); 76 for (i=0; i<16; i++) 77 out1[i] ^= op_c[i]; 78 79 for (i=0; i<8; i++) 80 mac_a[i] = out1[i]; 81 82 return; 83 } /* end of function f1 */ 84 85 86 87 /*------------------------------------------------------------------- 88 * Algorithms f2-f5 89 *------------------------------------------------------------------- 90 * 91 * Takes key K and random challenge RAND, and returns response RES, 92 * confidentiality key CK, integrity key IK and anonymity key AK. 93 * 94 *-----------------------------------------------------------------*/ 95 96 void f2345 ( u8 k[16], u8 rand[16], 97 u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] ) 98 { 99 u8 op_c[16]; 100 u8 temp[16]; 101 u8 out[16]; 102 u8 rijndaelInput[16]; 103 u8 i; 104 105 RijndaelKeySchedule( k ); 106 107 ComputeOPc( op_c, op ); 108 109 for (i=0; i<16; i++) 110 rijndaelInput[i] = rand[i] ^ op_c[i]; 111 RijndaelEncrypt( rijndaelInput, temp ); 112 113 /* To obtain output block OUT2: XOR OPc and TEMP, * 114 * rotate by r2=0, and XOR on the constant c2 (which * 115 * is all zeroes except that the last bit is 1). */ 116 117 for (i=0; i<16; i++) 118 rijndaelInput[i] = temp[i] ^ op_c[i]; 119 rijndaelInput[15] ^= 1; 120 121 RijndaelEncrypt( rijndaelInput, out ); 122 for (i=0; i<16; i++) 123 out[i] ^= op_c[i]; 124 125 for (i=0; i<8; i++) 126 res[i] = out[i+8]; 127 for (i=0; i<6; i++) 128 ak[i] = out[i]; 129 130 /* To obtain output block OUT3: XOR OPc and TEMP, * 131 * rotate by r3=32, and XOR on the constant c3 (which * 132 * is all zeroes except that the next to last bit is 1). */ 133 134 for (i=0; i<16; i++) 135 rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i]; 136 rijndaelInput[15] ^= 2; 137 138 RijndaelEncrypt( rijndaelInput, out ); 139 for (i=0; i<16; i++) 140 out[i] ^= op_c[i]; 141 142 for (i=0; i<16; i++) 143 ck[i] = out[i]; 144 145 /* To obtain output block OUT4: XOR OPc and TEMP, * 146 * rotate by r4=64, and XOR on the constant c4 (which * 147 * is all zeroes except that the 2nd from last bit is 1). */ 148 149 for (i=0; i<16; i++) 150 rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i]; 151 rijndaelInput[15] ^= 4; 152 153 RijndaelEncrypt( rijndaelInput, out ); 154 for (i=0; i<16; i++) 155 out[i] ^= op_c[i]; 156 157 for (i=0; i<16; i++) 158 ik[i] = out[i]; 159 160 return; 161 } /* end of function f2345 */ 162 163 164 /*------------------------------------------------------------------- 165 * Algorithm f1* 166 *------------------------------------------------------------------- 167 * 168 * Computes resynch authentication code MAC-S from key K, random 169 * challenge RAND, sequence number SQN and authentication management 170 * field AMF. 171 * 172 *-----------------------------------------------------------------*/ 173 174 void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], 175 u8 mac_s[8], u8 op[16] ) 176 { 177 u8 op_c[16]; 178 u8 temp[16]; 179 u8 in1[16]; 180 u8 out1[16]; 181 u8 rijndaelInput[16]; 182 u8 i; 183 184 RijndaelKeySchedule( k ); 185 186 ComputeOPc( op_c, op ); 187 188 for (i=0; i<16; i++) 189 rijndaelInput[i] = rand[i] ^ op_c[i]; 190 RijndaelEncrypt( rijndaelInput, temp ); 191 192 for (i=0; i<6; i++) 193 { 194 in1[i] = sqn[i]; 195 in1[i+8] = sqn[i]; 196 } 197 for (i=0; i<2; i++) 198 { 199 in1[i+6] = amf[i]; 200 in1[i+14] = amf[i]; 201 } 202 203 /* XOR op_c and in1, rotate by r1=64, and XOR * 204 * on the constant c1 (which is all zeroes) */ 205 206 for (i=0; i<16; i++) 207 rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; 208 209 /* XOR on the value temp computed before */ 210 211 for (i=0; i<16; i++) 212 rijndaelInput[i] ^= temp[i]; 213 214 RijndaelEncrypt( rijndaelInput, out1 ); 215 for (i=0; i<16; i++) 216 out1[i] ^= op_c[i]; 217 218 for (i=0; i<8; i++) 219 mac_s[i] = out1[i+8]; 220 221 return; 222 } /* end of function f1star */ 223 224 225 /*------------------------------------------------------------------- 226 * Algorithm f5* 227 *------------------------------------------------------------------- 228 * 229 * Takes key K and random challenge RAND, and returns resynch 230 * anonymity key AK. 231 * 232 *-----------------------------------------------------------------*/ 233 234 void f5star( u8 k[16], u8 rand[16], 235 u8 ak[6], u8 op[16] ) 236 { 237 u8 op_c[16]; 238 u8 temp[16]; 239 u8 out[16]; 240 u8 rijndaelInput[16]; 241 u8 i; 242 243 RijndaelKeySchedule( k ); 244 245 ComputeOPc( op_c, op ); 246 247 for (i=0; i<16; i++) 248 rijndaelInput[i] = rand[i] ^ op_c[i]; 249 RijndaelEncrypt( rijndaelInput, temp ); 250 251 /* To obtain output block OUT5: XOR OPc and TEMP, * 252 * rotate by r5=96, and XOR on the constant c5 (which * 253 * is all zeroes except that the 3rd from last bit is 1). */ 254 255 for (i=0; i<16; i++) 256 rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i]; 257 rijndaelInput[15] ^= 8; 258 259 RijndaelEncrypt( rijndaelInput, out ); 260 for (i=0; i<16; i++) 261 out[i] ^= op_c[i]; 262 263 for (i=0; i<6; i++) 264 ak[i] = out[i]; 265 266 return; 267 } /* end of function f5star */ 268 269 270 /*------------------------------------------------------------------- 271 * Function to compute OPc from OP and K. Assumes key schedule has 272 already been performed. 273 *-----------------------------------------------------------------*/ 274 275 void ComputeOPc( u8 op_c[16], u8 op[16] ) 276 { 277 u8 i; 278 279 RijndaelEncrypt( op, op_c ); 280 for (i=0; i<16; i++) 281 op_c[i] ^= op[i]; 282 283 return; 284 } /* end of function ComputeOPc */
| No admin address has been configured | ViewVC Help |
| Powered by ViewVC 1.0.8 |