00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 #include "common.h"
00027 #include "crypto/aes_wrap.h"
00028 #include "milenage.h"
00029
00030
00042 int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
00043 const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s)
00044 {
00045 u8 tmp1[16], tmp2[16], tmp3[16];
00046 int i;
00047
00048
00049 for (i = 0; i < 16; i++)
00050 tmp1[i] = _rand[i] ^ opc[i];
00051 if (aes_128_encrypt_block(k, tmp1, tmp1))
00052 return -1;
00053
00054
00055 os_memcpy(tmp2, sqn, 6);
00056 os_memcpy(tmp2 + 6, amf, 2);
00057 os_memcpy(tmp2 + 8, tmp2, 8);
00058
00059
00060
00061
00062 for (i = 0; i < 16; i++)
00063 tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i];
00064
00065 for (i = 0; i < 16; i++)
00066 tmp3[i] ^= tmp1[i];
00067
00068
00069
00070 if (aes_128_encrypt_block(k, tmp3, tmp1))
00071 return -1;
00072 for (i = 0; i < 16; i++)
00073 tmp1[i] ^= opc[i];
00074 if (mac_a)
00075 os_memcpy(mac_a, tmp1, 8);
00076 if (mac_s)
00077 os_memcpy(mac_s, tmp1 + 8, 8);
00078 return 0;
00079 }
00080
00081
00094 int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
00095 u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar)
00096 {
00097 u8 tmp1[16], tmp2[16], tmp3[16];
00098 int i;
00099
00100
00101 for (i = 0; i < 16; i++)
00102 tmp1[i] = _rand[i] ^ opc[i];
00103 if (aes_128_encrypt_block(k, tmp1, tmp2))
00104 return -1;
00105
00106
00107
00108
00109
00110
00111
00112
00113 for (i = 0; i < 16; i++)
00114 tmp1[i] = tmp2[i] ^ opc[i];
00115 tmp1[15] ^= 1;
00116
00117 if (aes_128_encrypt_block(k, tmp1, tmp3))
00118 return -1;
00119 for (i = 0; i < 16; i++)
00120 tmp3[i] ^= opc[i];
00121 if (res)
00122 os_memcpy(res, tmp3 + 8, 8);
00123 if (ak)
00124 os_memcpy(ak, tmp3, 6);
00125
00126
00127 if (ck) {
00128
00129 for (i = 0; i < 16; i++)
00130 tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i];
00131 tmp1[15] ^= 2;
00132 if (aes_128_encrypt_block(k, tmp1, ck))
00133 return -1;
00134 for (i = 0; i < 16; i++)
00135 ck[i] ^= opc[i];
00136 }
00137
00138
00139 if (ik) {
00140
00141 for (i = 0; i < 16; i++)
00142 tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i];
00143 tmp1[15] ^= 4;
00144 if (aes_128_encrypt_block(k, tmp1, ik))
00145 return -1;
00146 for (i = 0; i < 16; i++)
00147 ik[i] ^= opc[i];
00148 }
00149
00150
00151 if (akstar) {
00152
00153 for (i = 0; i < 16; i++)
00154 tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i];
00155 tmp1[15] ^= 8;
00156 if (aes_128_encrypt_block(k, tmp1, tmp1))
00157 return -1;
00158 for (i = 0; i < 6; i++)
00159 akstar[i] = tmp1[i] ^ opc[i];
00160 }
00161
00162 return 0;
00163 }
00164
00165
00179 void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
00180 const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
00181 u8 *ck, u8 *res, size_t *res_len)
00182 {
00183 int i;
00184 u8 mac_a[8], ak[6];
00185
00186 if (*res_len < 8) {
00187 *res_len = 0;
00188 return;
00189 }
00190 if (milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
00191 milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) {
00192 *res_len = 0;
00193 return;
00194 }
00195 *res_len = 8;
00196
00197
00198 for (i = 0; i < 6; i++)
00199 autn[i] = sqn[i] ^ ak[i];
00200 os_memcpy(autn + 6, amf, 2);
00201 os_memcpy(autn + 8, mac_a, 8);
00202 }
00203
00204
00214 int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
00215 u8 *sqn)
00216 {
00217 u8 amf[2] = { 0x00, 0x00 };
00218 u8 ak[6], mac_s[8];
00219 int i;
00220
00221 if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
00222 return -1;
00223 for (i = 0; i < 6; i++)
00224 sqn[i] = auts[i] ^ ak[i];
00225 if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
00226 memcmp(mac_s, auts + 6, 8) != 0)
00227 return -1;
00228 return 0;
00229 }
00230
00231
00241 int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc)
00242 {
00243 u8 res[8], ck[16], ik[16];
00244 int i;
00245
00246 if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
00247 return -1;
00248
00249 for (i = 0; i < 8; i++)
00250 kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8];
00251
00252 #ifdef GSM_MILENAGE_ALT_SRES
00253 os_memcpy(sres, res, 4);
00254 #else
00255 for (i = 0; i < 4; i++)
00256 sres[i] = res[i] ^ res[i + 4];
00257 #endif
00258 return 0;
00259 }
00260
00261
00276 int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
00277 const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
00278 u8 *auts)
00279 {
00280 int i;
00281 u8 mac_a[8], ak[6], rx_sqn[6];
00282 const u8 *amf;
00283
00284 wpa_hexdump(MSG_DEBUG, "Milenage: AUTN", autn, 16);
00285 wpa_hexdump(MSG_DEBUG, "Milenage: RAND", _rand, 16);
00286
00287 if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
00288 return -1;
00289
00290 *res_len = 8;
00291 wpa_hexdump_key(MSG_DEBUG, "Milenage: RES", res, *res_len);
00292 wpa_hexdump_key(MSG_DEBUG, "Milenage: CK", ck, 16);
00293 wpa_hexdump_key(MSG_DEBUG, "Milenage: IK", ik, 16);
00294 wpa_hexdump_key(MSG_DEBUG, "Milenage: AK", ak, 6);
00295
00296
00297 for (i = 0; i < 6; i++)
00298 rx_sqn[i] = autn[i] ^ ak[i];
00299 wpa_hexdump(MSG_DEBUG, "Milenage: SQN", rx_sqn, 6);
00300
00301 if (os_memcmp(rx_sqn, sqn, 6) <= 0) {
00302 u8 auts_amf[2] = { 0x00, 0x00 };
00303 if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
00304 return -1;
00305 wpa_hexdump_key(MSG_DEBUG, "Milenage: AK*", ak, 6);
00306 for (i = 0; i < 6; i++)
00307 auts[i] = sqn[i] ^ ak[i];
00308 if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
00309 return -1;
00310 wpa_hexdump(MSG_DEBUG, "Milenage: AUTS", auts, 14);
00311 return -2;
00312 }
00313
00314 amf = autn + 6;
00315 wpa_hexdump(MSG_DEBUG, "Milenage: AMF", amf, 2);
00316 if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
00317 return -1;
00318
00319 wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8);
00320
00321 if (os_memcmp(mac_a, autn + 8, 8) != 0) {
00322 wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch");
00323 wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A",
00324 autn + 8, 8);
00325 return -1;
00326 }
00327
00328 return 0;
00329 }