eap_ikev2_common.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * EAP-IKEv2 common routines
  3. * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "eap_defs.h"
  17. #include "eap_common.h"
  18. #include "ikev2_common.h"
  19. #include "eap_ikev2_common.h"
  20. int eap_ikev2_derive_keymat(int prf, struct ikev2_keys *keys,
  21. const u8 *i_nonce, size_t i_nonce_len,
  22. const u8 *r_nonce, size_t r_nonce_len,
  23. u8 *keymat)
  24. {
  25. u8 *nonces;
  26. size_t nlen;
  27. /* KEYMAT = prf+(SK_d, Ni | Nr) */
  28. if (keys->SK_d == NULL || i_nonce == NULL || r_nonce == NULL)
  29. return -1;
  30. nlen = i_nonce_len + r_nonce_len;
  31. nonces = os_malloc(nlen);
  32. if (nonces == NULL)
  33. return -1;
  34. os_memcpy(nonces, i_nonce, i_nonce_len);
  35. os_memcpy(nonces + i_nonce_len, r_nonce, r_nonce_len);
  36. if (ikev2_prf_plus(prf, keys->SK_d, keys->SK_d_len, nonces, nlen,
  37. keymat, EAP_MSK_LEN + EAP_EMSK_LEN)) {
  38. os_free(nonces);
  39. return -1;
  40. }
  41. os_free(nonces);
  42. wpa_hexdump_key(MSG_DEBUG, "EAP-IKEV2: KEYMAT",
  43. keymat, EAP_MSK_LEN + EAP_EMSK_LEN);
  44. return 0;
  45. }
  46. struct wpabuf * eap_ikev2_build_frag_ack(u8 id, u8 code)
  47. {
  48. struct wpabuf *msg;
  49. #ifdef CCNS_PL
  50. msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 1, code, id);
  51. if (msg == NULL) {
  52. wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
  53. "for fragment ack");
  54. return NULL;
  55. }
  56. wpabuf_put_u8(msg, 0); /* Flags */
  57. #else /* CCNS_PL */
  58. msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 0, code, id);
  59. if (msg == NULL) {
  60. wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
  61. "for fragment ack");
  62. return NULL;
  63. }
  64. #endif /* CCNS_PL */
  65. wpa_printf(MSG_DEBUG, "EAP-IKEV2: Send fragment ack");
  66. return msg;
  67. }
  68. int eap_ikev2_validate_icv(int integ_alg, struct ikev2_keys *keys,
  69. int initiator, const struct wpabuf *msg,
  70. const u8 *pos, const u8 *end)
  71. {
  72. const struct ikev2_integ_alg *integ;
  73. size_t icv_len;
  74. u8 icv[IKEV2_MAX_HASH_LEN];
  75. const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
  76. integ = ikev2_get_integ(integ_alg);
  77. if (integ == NULL) {
  78. wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
  79. "transform / cannot validate ICV");
  80. return -1;
  81. }
  82. icv_len = integ->hash_len;
  83. if (end - pos < (int) icv_len) {
  84. wpa_printf(MSG_DEBUG, "EAP-IKEV2: Not enough room in the "
  85. "message for Integrity Checksum Data");
  86. return -1;
  87. }
  88. if (SK_a == NULL) {
  89. wpa_printf(MSG_DEBUG, "EAP-IKEV2: No SK_a for ICV validation");
  90. return -1;
  91. }
  92. if (ikev2_integ_hash(integ_alg, SK_a, keys->SK_integ_len,
  93. wpabuf_head(msg),
  94. wpabuf_len(msg) - icv_len, icv) < 0) {
  95. wpa_printf(MSG_INFO, "EAP-IKEV2: Could not calculate ICV");
  96. return -1;
  97. }
  98. if (os_memcmp(icv, end - icv_len, icv_len) != 0) {
  99. wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV");
  100. wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV",
  101. icv, icv_len);
  102. wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Received ICV",
  103. end - icv_len, icv_len);
  104. return -1;
  105. }
  106. wpa_printf(MSG_DEBUG, "EAP-IKEV2: Valid Integrity Checksum Data in "
  107. "the received message");
  108. return icv_len;
  109. }