milenage.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * 3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
  3. * Copyright (c) 2006-2007 <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. *
  8. * This file implements an example authentication algorithm defined for 3GPP
  9. * AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow
  10. * EAP-AKA to be tested properly with real USIM cards.
  11. *
  12. * This implementations assumes that the r1..r5 and c1..c5 constants defined in
  13. * TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00,
  14. * c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to
  15. * be AES (Rijndael).
  16. */
  17. #include "includes.h"
  18. #include "common.h"
  19. #include "crypto/aes_wrap.h"
  20. #include "milenage.h"
  21. /**
  22. * milenage_f1 - Milenage f1 and f1* algorithms
  23. * @opc: OPc = 128-bit value derived from OP and K
  24. * @k: K = 128-bit subscriber key
  25. * @_rand: RAND = 128-bit random challenge
  26. * @sqn: SQN = 48-bit sequence number
  27. * @amf: AMF = 16-bit authentication management field
  28. * @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL
  29. * @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
  30. * Returns: 0 on success, -1 on failure
  31. */
  32. int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
  33. const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s)
  34. {
  35. u8 tmp1[16], tmp2[16], tmp3[16];
  36. int i;
  37. /* tmp1 = TEMP = E_K(RAND XOR OP_C) */
  38. for (i = 0; i < 16; i++)
  39. tmp1[i] = _rand[i] ^ opc[i];
  40. if (aes_128_encrypt_block(k, tmp1, tmp1))
  41. return -1;
  42. /* tmp2 = IN1 = SQN || AMF || SQN || AMF */
  43. os_memcpy(tmp2, sqn, 6);
  44. os_memcpy(tmp2 + 6, amf, 2);
  45. os_memcpy(tmp2 + 8, tmp2, 8);
  46. /* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */
  47. /* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */
  48. for (i = 0; i < 16; i++)
  49. tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i];
  50. /* XOR with TEMP = E_K(RAND XOR OP_C) */
  51. for (i = 0; i < 16; i++)
  52. tmp3[i] ^= tmp1[i];
  53. /* XOR with c1 (= ..00, i.e., NOP) */
  54. /* f1 || f1* = E_K(tmp3) XOR OP_c */
  55. if (aes_128_encrypt_block(k, tmp3, tmp1))
  56. return -1;
  57. for (i = 0; i < 16; i++)
  58. tmp1[i] ^= opc[i];
  59. if (mac_a)
  60. os_memcpy(mac_a, tmp1, 8); /* f1 */
  61. if (mac_s)
  62. os_memcpy(mac_s, tmp1 + 8, 8); /* f1* */
  63. return 0;
  64. }
  65. /**
  66. * milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
  67. * @opc: OPc = 128-bit value derived from OP and K
  68. * @k: K = 128-bit subscriber key
  69. * @_rand: RAND = 128-bit random challenge
  70. * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
  71. * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
  72. * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
  73. * @ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL
  74. * @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
  75. * Returns: 0 on success, -1 on failure
  76. */
  77. int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
  78. u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar)
  79. {
  80. u8 tmp1[16], tmp2[16], tmp3[16];
  81. int i;
  82. /* tmp2 = TEMP = E_K(RAND XOR OP_C) */
  83. for (i = 0; i < 16; i++)
  84. tmp1[i] = _rand[i] ^ opc[i];
  85. if (aes_128_encrypt_block(k, tmp1, tmp2))
  86. return -1;
  87. /* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */
  88. /* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */
  89. /* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */
  90. /* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */
  91. /* f2 and f5 */
  92. /* rotate by r2 (= 0, i.e., NOP) */
  93. for (i = 0; i < 16; i++)
  94. tmp1[i] = tmp2[i] ^ opc[i];
  95. tmp1[15] ^= 1; /* XOR c2 (= ..01) */
  96. /* f5 || f2 = E_K(tmp1) XOR OP_c */
  97. if (aes_128_encrypt_block(k, tmp1, tmp3))
  98. return -1;
  99. for (i = 0; i < 16; i++)
  100. tmp3[i] ^= opc[i];
  101. if (res)
  102. os_memcpy(res, tmp3 + 8, 8); /* f2 */
  103. if (ak)
  104. os_memcpy(ak, tmp3, 6); /* f5 */
  105. /* f3 */
  106. if (ck) {
  107. /* rotate by r3 = 0x20 = 4 bytes */
  108. for (i = 0; i < 16; i++)
  109. tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i];
  110. tmp1[15] ^= 2; /* XOR c3 (= ..02) */
  111. if (aes_128_encrypt_block(k, tmp1, ck))
  112. return -1;
  113. for (i = 0; i < 16; i++)
  114. ck[i] ^= opc[i];
  115. }
  116. /* f4 */
  117. if (ik) {
  118. /* rotate by r4 = 0x40 = 8 bytes */
  119. for (i = 0; i < 16; i++)
  120. tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i];
  121. tmp1[15] ^= 4; /* XOR c4 (= ..04) */
  122. if (aes_128_encrypt_block(k, tmp1, ik))
  123. return -1;
  124. for (i = 0; i < 16; i++)
  125. ik[i] ^= opc[i];
  126. }
  127. /* f5* */
  128. if (akstar) {
  129. /* rotate by r5 = 0x60 = 12 bytes */
  130. for (i = 0; i < 16; i++)
  131. tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i];
  132. tmp1[15] ^= 8; /* XOR c5 (= ..08) */
  133. if (aes_128_encrypt_block(k, tmp1, tmp1))
  134. return -1;
  135. for (i = 0; i < 6; i++)
  136. akstar[i] = tmp1[i] ^ opc[i];
  137. }
  138. return 0;
  139. }
  140. /**
  141. * milenage_generate - Generate AKA AUTN,IK,CK,RES
  142. * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
  143. * @amf: AMF = 16-bit authentication management field
  144. * @k: K = 128-bit subscriber key
  145. * @sqn: SQN = 48-bit sequence number
  146. * @_rand: RAND = 128-bit random challenge
  147. * @autn: Buffer for AUTN = 128-bit authentication token
  148. * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
  149. * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
  150. * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
  151. * @res_len: Max length for res; set to used length or 0 on failure
  152. */
  153. void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
  154. const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
  155. u8 *ck, u8 *res, size_t *res_len)
  156. {
  157. int i;
  158. u8 mac_a[8], ak[6];
  159. if (*res_len < 8) {
  160. *res_len = 0;
  161. return;
  162. }
  163. if (milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
  164. milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) {
  165. *res_len = 0;
  166. return;
  167. }
  168. *res_len = 8;
  169. /* AUTN = (SQN ^ AK) || AMF || MAC */
  170. for (i = 0; i < 6; i++)
  171. autn[i] = sqn[i] ^ ak[i];
  172. os_memcpy(autn + 6, amf, 2);
  173. os_memcpy(autn + 8, mac_a, 8);
  174. }
  175. /**
  176. * milenage_auts - Milenage AUTS validation
  177. * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
  178. * @k: K = 128-bit subscriber key
  179. * @_rand: RAND = 128-bit random challenge
  180. * @auts: AUTS = 112-bit authentication token from client
  181. * @sqn: Buffer for SQN = 48-bit sequence number
  182. * Returns: 0 = success (sqn filled), -1 on failure
  183. */
  184. int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
  185. u8 *sqn)
  186. {
  187. u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
  188. u8 ak[6], mac_s[8];
  189. int i;
  190. if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
  191. return -1;
  192. for (i = 0; i < 6; i++)
  193. sqn[i] = auts[i] ^ ak[i];
  194. if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
  195. memcmp(mac_s, auts + 6, 8) != 0)
  196. return -1;
  197. return 0;
  198. }
  199. /**
  200. * gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet
  201. * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
  202. * @k: K = 128-bit subscriber key
  203. * @_rand: RAND = 128-bit random challenge
  204. * @sres: Buffer for SRES = 32-bit SRES
  205. * @kc: Buffer for Kc = 64-bit Kc
  206. * Returns: 0 on success, -1 on failure
  207. */
  208. int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc)
  209. {
  210. u8 res[8], ck[16], ik[16];
  211. int i;
  212. if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
  213. return -1;
  214. for (i = 0; i < 8; i++)
  215. kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8];
  216. #ifdef GSM_MILENAGE_ALT_SRES
  217. os_memcpy(sres, res, 4);
  218. #else /* GSM_MILENAGE_ALT_SRES */
  219. for (i = 0; i < 4; i++)
  220. sres[i] = res[i] ^ res[i + 4];
  221. #endif /* GSM_MILENAGE_ALT_SRES */
  222. return 0;
  223. }
  224. /**
  225. * milenage_generate - Generate AKA AUTN,IK,CK,RES
  226. * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
  227. * @k: K = 128-bit subscriber key
  228. * @sqn: SQN = 48-bit sequence number
  229. * @_rand: RAND = 128-bit random challenge
  230. * @autn: AUTN = 128-bit authentication token
  231. * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
  232. * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
  233. * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
  234. * @res_len: Variable that will be set to RES length
  235. * @auts: 112-bit buffer for AUTS
  236. * Returns: 0 on success, -1 on failure, or -2 on synchronization failure
  237. */
  238. int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
  239. const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
  240. u8 *auts)
  241. {
  242. int i;
  243. u8 mac_a[8], ak[6], rx_sqn[6];
  244. const u8 *amf;
  245. wpa_hexdump(MSG_DEBUG, "Milenage: AUTN", autn, 16);
  246. wpa_hexdump(MSG_DEBUG, "Milenage: RAND", _rand, 16);
  247. if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
  248. return -1;
  249. *res_len = 8;
  250. wpa_hexdump_key(MSG_DEBUG, "Milenage: RES", res, *res_len);
  251. wpa_hexdump_key(MSG_DEBUG, "Milenage: CK", ck, 16);
  252. wpa_hexdump_key(MSG_DEBUG, "Milenage: IK", ik, 16);
  253. wpa_hexdump_key(MSG_DEBUG, "Milenage: AK", ak, 6);
  254. /* AUTN = (SQN ^ AK) || AMF || MAC */
  255. for (i = 0; i < 6; i++)
  256. rx_sqn[i] = autn[i] ^ ak[i];
  257. wpa_hexdump(MSG_DEBUG, "Milenage: SQN", rx_sqn, 6);
  258. if (os_memcmp(rx_sqn, sqn, 6) <= 0) {
  259. u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
  260. if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
  261. return -1;
  262. wpa_hexdump_key(MSG_DEBUG, "Milenage: AK*", ak, 6);
  263. for (i = 0; i < 6; i++)
  264. auts[i] = sqn[i] ^ ak[i];
  265. if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
  266. return -1;
  267. wpa_hexdump(MSG_DEBUG, "Milenage: AUTS", auts, 14);
  268. return -2;
  269. }
  270. amf = autn + 6;
  271. wpa_hexdump(MSG_DEBUG, "Milenage: AMF", amf, 2);
  272. if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
  273. return -1;
  274. wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8);
  275. if (os_memcmp(mac_a, autn + 8, 8) != 0) {
  276. wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch");
  277. wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A",
  278. autn + 8, 8);
  279. return -1;
  280. }
  281. return 0;
  282. }