28 RCSID(
"$Id: b082b12e7b910d5dc3e5960d26de4ae5cfdb9f43 $")
33 #include "../../eap.h"
38 #include <freeradius-devel/rad_assert.h>
82 words[0] = htons(
sizeof(words[1]));
93 newvp->vp_integer = ess->
sim_id++;
102 p = talloc_array(newvp, uint8_t, 2);
136 REDEBUG(
"Found Ki, but missing EAP-Sim-Algo-Version");
144 switch (algo_version->vp_integer) {
160 REDEBUG(
"Comp128-4 algorithm is not supported as details have not yet been published. "
161 "If you have details of this algorithm please contact the FreeRADIUS "
166 REDEBUG(
"Unknown/unsupported algorithm Comp128-%i", algo_version->vp_integer);
173 RDEBUG2(
"Generated following triplets for round %i:", idx);
178 p += sprintf(p,
"%02x", ess->
keys.
rand[idx][i]);
180 RDEBUG2(
"RAND : 0x%s", buffer);
184 p += sprintf(p,
"%02x", ess->
keys.
sres[idx][i]);
186 RDEBUG2(
"SRES : 0x%s", buffer);
190 p += sprintf(p,
"%02x", ess->
keys.
Kc[idx][i]);
205 REDEBUG(
"control:EAP-SIM-RAND%i not found", idx + 1);
210 idx + 1, vp->vp_length);
218 REDEBUG(
"control:EAP-SIM-SRES%i not found", idx + 1);
223 idx + 1, vp->vp_length);
231 REDEBUG(
"control:EAP-SIM-Kc%i not found", idx + 1);
235 REDEBUG(
"control:EAP-SIM-Kc%i is not 8 bytes, got %zu bytes", idx + 1, vp->vp_length);
241 idx + 1, vp->vp_length);
288 outvps = &packet->
vps;
291 RDEBUG2(
"EAP-SIM decoded packet");
314 newvp->vp_integer = ess->
sim_id++;
327 if (newvp && newvp->vp_length > 2) {
330 memcpy(&len, newvp->vp_octets,
sizeof(uint16_t));
343 #ifdef EAP_SIM_DEBUG_PRF
369 #ifndef EAPTLS_MPPE_KEY_LEN
370 #define EAPTLS_MPPE_KEY_LEN 32
393 vp->vp_integer = ess->
sim_id++;
441 ess->
state = newstate;
456 REQUEST *request = eap_session->request;
462 RDEBUG2(
"No space for EAP-SIM state");
466 eap_session->opaque = ess;
507 if (!nonce_vp || !selectedversion_vp) {
508 RDEBUG2(
"Client did not select a version and send a NONCE");
517 if (selectedversion_vp->vp_length < 2) {
518 REDEBUG(
"EAP-SIM version field is too short");
521 memcpy(&simversion, selectedversion_vp->vp_strvalue,
sizeof(simversion));
522 simversion = ntohs(simversion);
524 REDEBUG(
"EAP-SIM version %i is unknown", simversion);
536 if(nonce_vp->vp_length != 18) {
537 REDEBUG(
"EAP-SIM nonce_mt must be 16 bytes (+2 bytes padding), not %zu", nonce_vp->vp_length);
540 memcpy(ess->
keys.
nonce_mt, nonce_vp->vp_strvalue + 2, 16);
563 uint8_t *p = srescat;
591 sprintf(m,
"%02x", calcmac[i]);
594 REDEBUG(
"Calculated MAC (%s) did not match", macline);
627 if (!success)
return 0;
634 REDEBUG2(
"No subtype attribute was created, message dropped");
637 subtype = vp->vp_integer;
646 switch (ess->
state) {
2nd highest priority debug messages (-xx | -X).
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
#define RINDENT()
Indent R* messages by one level.
void comp128v1(uint8_t *sres, uint8_t *kc, uint8_t const *ki, uint8_t const *rand)
Calculate comp128v1 sres and kc from ki and rand.
VALUE_PAIR * fr_pair_afrom_num(TALLOC_CTX *ctx, unsigned int vendor, unsigned int attr)
Create a new valuepair.
#define RDEBUG_ENABLED2
True if request debug level 1-2 messages are enabled.
uint32_t fr_rand(void)
Return a 32-bit random number.
static int eap_sim_get_challenge(eap_session_t *eap_session, VALUE_PAIR *vps, int idx, eap_sim_state_t *ess)
uint8_t sres[3][EAPSIM_SRES_SIZE]
#define REDEBUG2(fmt,...)
static int process_eap_sim_start(eap_session_t *eap_session, VALUE_PAIR *vps)
Process an EAP-Sim/Response/Start.
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
void comp128v23(uint8_t *sres, uint8_t *kc, uint8_t const *ki, uint8_t const *rand, bool v2)
Calculate comp128v2 or comp128v3 sres and kc from ki and rand.
eap_packet_t * request
Packet we will send to the peer.
void * opaque
Opaque data used by EAP methods.
static void eap_sim_stateenter(eap_session_t *eap_session, eap_sim_state_t *ess, enum eapsim_serverstates newstate)
Run the server state machine.
REQUEST * request
Request that contains the response we're processing.
enum eapsim_serverstates state
static int eap_sim_sendchallenge(eap_session_t *eap_session)
Send the challenge itself.
static int mod_session_init(void *instance, eap_session_t *eap_session)
uint8_t rand[3][EAPSIM_RAND_SIZE]
static int process_eap_sim_challenge(eap_session_t *eap_session, VALUE_PAIR *vps)
Process an EAP-Sim/Response/Challenge.
static int eap_sim_sendstart(eap_session_t *eap_session)
int unmap_eapsim_basictypes(RADIUS_PACKET *r, uint8_t *attr, unsigned int attrlen)
static int eap_sim_sendsuccess(eap_session_t *eap_session)
struct eap_sim_server_state eap_sim_state_t
void fr_pair_add(VALUE_PAIR **head, VALUE_PAIR *vp)
Add a VP to the end of the list.
Tracks the progress of a single session of any EAP method.
int eapsim_checkmac(TALLOC_CTX *ctx, VALUE_PAIR *rvps, uint8_t key[8], uint8_t *extra, int extralen, uint8_t calcmac[20])
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
int map_eapsim_basictypes(RADIUS_PACKET *r, eap_packet_t *ep)
Stores an attribute, a value and various bits of other data.
RADIUS_PACKET * reply
Outgoing response.
static int eap_sim_compose(eap_session_t *eap_session)
#define REXDENT()
Exdent (unindent) R* messages by one level.
char const * name
The name of the sub-module (without rlm_ prefix).
void eapsim_dump_mk(struct eapsim_keys *ek)
void rdebug_pair_list(log_lvl_t level, REQUEST *, VALUE_PAIR *, char const *)
Print a list of VALUE_PAIRs.
rlm_eap_module_t rlm_eap_sim
char * identity
NAI (User-Name) from EAP-Identity.
uint8_t identity[MAX_STRING_LEN]
static int CC_HINT(nonnull)
uint8_t K_aut[EAPSIM_AUTH_SIZE]
void fr_pair_value_memsteal(VALUE_PAIR *vp, uint8_t const *src)
Reparent an allocated octet buffer to a VALUE_PAIR.
Interface to call EAP sub mdoules.
uint8_t Kc[3][EAPSIM_KC_SIZE]
uint8_t versionlist[MAX_STRING_LEN]
static int mod_process(UNUSED void *arg, eap_session_t *eap_session)
Authenticate a previously sent challenge.
RADIUS_PACKET * packet
Incoming request.
void eapsim_calculate_keys(struct eapsim_keys *ek)
#define EAPSIM_CALCMAC_SIZE
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
eap_packet_t * response
Packet we received from the peer.
uint8_t nonce_mt[EAPSIM_NONCEMT_SIZE]
void fr_pair_replace(VALUE_PAIR **head, VALUE_PAIR *add)
Replace all matching VPs.
void fr_pair_value_memcpy(VALUE_PAIR *vp, uint8_t const *src, size_t len)
Copy data into an "octets" data type.
void eap_add_reply(REQUEST *request, char const *name, uint8_t const *value, int len)
#define EAPTLS_MPPE_KEY_LEN