The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Functions | Variables
crypto.c File Reference

Calculate keys from GSM vectors. More...

#include <stdio.h>
#include <stdlib.h>
#include <freeradius-devel/protocol/eap/aka-sim/dictionary.h>
#include <freeradius-devel/eap/types.h>
#include <freeradius-devel/sim/common.h>
#include <freeradius-devel/sim/milenage.h>
#include <freeradius-devel/tls/base.h>
#include <freeradius-devel/tls/strerror.h>
#include <freeradius-devel/util/atexit.h>
#include <freeradius-devel/util/proto.h>
#include <freeradius-devel/util/rand.h>
#include <freeradius-devel/util/sha1.h>
#include <openssl/evp.h>
#include "base.h"
#include "attrs.h"
#include "crypto_priv.h"
+ Include dependency graph for crypto.c:

Go to the source code of this file.

Macros

#define KDF_1_S_REAUTH_STATIC   "EAP-AKA' re-auth"
 
#define KDF_1_S_STATIC   "EAP-AKA'"
 

Functions

static int _evp_cipher_ctx_free_on_exit (void *arg)
 
static int _fr_aka_sim_crypto_free_checkcode (fr_aka_sim_checkcode_t *checkcode)
 Free OpenSSL memory associated with our checkcode ctx. More...
 
static int aka_prime_prf (uint8_t *out, size_t outlen, uint8_t const *key, size_t key_len, uint8_t const *in, size_t in_len)
 PRF as described in RFC 5448 (EAP-AKA') section 3.4.1. More...
 
EVP_CIPHER_CTX * aka_sim_crypto_cipher_ctx (void)
 Allocate and reset a resumable EVP_CIPHER_CTX for each thread. More...
 
void aka_sim_crypto_cipher_ctx_free (void)
 Explicitly free all thread load cipher ctxs. More...
 
static int ck_ik_prime_derive (fr_aka_sim_keys_t *keys)
 Key Derivation Function (CK', IK') as specified in 3GPP.33.402. More...
 
ssize_t fr_aka_sim_crypto_finalise_checkcode (TALLOC_CTX *ctx, uint8_t **out, fr_aka_sim_checkcode_t *checkcode)
 Write out the final checkcode value. More...
 
int fr_aka_sim_crypto_gsm_kdf_0 (fr_aka_sim_keys_t *keys)
 Key Derivation Function as described in RFC4186 (EAP-SIM) section 7. More...
 
int fr_aka_sim_crypto_init_checkcode (TALLOC_CTX *ctx, fr_aka_sim_checkcode_t **checkcode, EVP_MD const *md)
 Initialise checkcode message digest. More...
 
int fr_aka_sim_crypto_kdf_0_reauth (fr_aka_sim_keys_t *keys)
 Key Derivation Function (Fast-Reauthentication) as described in RFC4186/7 (EAP-SIM/AKA) section 7. More...
 
void fr_aka_sim_crypto_keys_init_kdf_0_reauth (fr_aka_sim_keys_t *keys, uint8_t const mk[static AKA_SIM_MK_SIZE], uint16_t counter)
 Initialise fr_aka_sim_keys_t with EAP-SIM reauthentication data. More...
 
void fr_aka_sim_crypto_keys_init_umts_kdf_1_reauth (fr_aka_sim_keys_t *keys, uint8_t const mk[static AKA_PRIME_MK_REAUTH_SIZE], uint16_t counter)
 Initialise fr_aka_sim_keys_t with EAP-AKA['] reauthentication data. More...
 
void fr_aka_sim_crypto_keys_log (request_t *request, fr_aka_sim_keys_t *keys)
 Dump the current state of all keys associated with the EAP SIM session. More...
 
ssize_t fr_aka_sim_crypto_sign_packet (uint8_t out[static AKA_SIM_MAC_DIGEST_SIZE], eap_packet_t *eap_packet, bool zero_mac, EVP_MD const *md, uint8_t const *key, size_t const key_len, uint8_t const *hmac_extra, size_t const hmac_extra_len)
 Calculate the digest value for a packet. More...
 
int fr_aka_sim_crypto_umts_kdf_0 (fr_aka_sim_keys_t *keys)
 Key Derivation Function as described in RFC4187 (EAP-AKA) section 7. More...
 
int fr_aka_sim_crypto_umts_kdf_1 (fr_aka_sim_keys_t *keys)
 Key Derivation Function as described in RFC 5448 (EAP-AKA') section 3.3. More...
 
int fr_aka_sim_crypto_umts_kdf_1_reauth (fr_aka_sim_keys_t *keys)
 Key Derivation Function (Fast-Reauthentication) as described in RFC 5448 (EAP-AKA') section 3.3. More...
 
int fr_aka_sim_crypto_update_checkcode (fr_aka_sim_checkcode_t *checkcode, eap_packet_t *eap_packet)
 Digest a packet, updating the checkcode. More...
 
static int fr_aka_sim_find_mac (uint8_t const **out, uint8_t *data, size_t data_len)
 Locate the start of the AT_MAC value in the buffer. More...
 

Variables

static _Thread_local EVP_CIPHER_CTX * evp_chipher_ctx
 Used for every non-persistent EVP_CIPHER operation in this library. More...
 

Detailed Description

Calculate keys from GSM vectors.

The development of the original EAP/SIM support was funded by Internet Foundation Austria (http://www.nic.at/ipa). The original EAP-SIM PRF functions were written by Michael Richardson mcr@s.nosp@m.ande.nosp@m.lman..nosp@m.otta.nosp@m.wa.on.nosp@m..ca, but these have since been replaced.

Author
Arran Cudbard-Bell (a.cud.nosp@m.bard.nosp@m.b@fre.nosp@m.erad.nosp@m.ius.o.nosp@m.rg)

Definition in file crypto.c.

Macro Definition Documentation

◆ KDF_1_S_REAUTH_STATIC

#define KDF_1_S_REAUTH_STATIC   "EAP-AKA' re-auth"

◆ KDF_1_S_STATIC

#define KDF_1_S_STATIC   "EAP-AKA'"

Function Documentation

◆ _evp_cipher_ctx_free_on_exit()

static int _evp_cipher_ctx_free_on_exit ( void *  arg)
static

Definition at line 59 of file crypto.c.

+ Here is the caller graph for this function:

◆ _fr_aka_sim_crypto_free_checkcode()

static int _fr_aka_sim_crypto_free_checkcode ( fr_aka_sim_checkcode_t checkcode)
static

Free OpenSSL memory associated with our checkcode ctx.

Parameters
[in]checkcodeto free.
Returns
0

Definition at line 98 of file crypto.c.

+ Here is the caller graph for this function:

◆ aka_prime_prf()

static int aka_prime_prf ( uint8_t out,
size_t  outlen,
uint8_t const *  key,
size_t  key_len,
uint8_t const *  in,
size_t  in_len 
)
static

PRF as described in RFC 5448 (EAP-AKA') section 3.4.1.

       PRF'(K,S) = T1 | T2 | T3 | T4 | ...

       where:
       T1 = HMAC-SHA-256 (K, S | 0x01)
       T2 = HMAC-SHA-256 (K, T1 | S | 0x02)
       T3 = HMAC-SHA-256 (K, T2 | S | 0x03)
       T4 = HMAC-SHA-256 (K, T3 | S | 0x04)
       ...

PRF' produces as many bits of output as is needed.

Parameters
[out]outWhere to write the output of the PRF.
[in]outlenhow many bytes need to be generated.
[in]keyfor the PRF (K).
[in]key_lenLength of key data.
[in]inData to feed into the PRF (S).
[in]in_lenLength of input data.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 773 of file crypto.c.

+ Here is the caller graph for this function:

◆ aka_sim_crypto_cipher_ctx()

EVP_CIPHER_CTX* aka_sim_crypto_cipher_ctx ( void  )

Allocate and reset a resumable EVP_CIPHER_CTX for each thread.

No two crypto operations ever occur simultaneously in the same thread, so it's fine to use a single context that persists for all operations.

Definition at line 70 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ aka_sim_crypto_cipher_ctx_free()

void aka_sim_crypto_cipher_ctx_free ( void  )

Explicitly free all thread load cipher ctxs.

Definition at line 87 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ck_ik_prime_derive()

static int ck_ik_prime_derive ( fr_aka_sim_keys_t keys)
static

Key Derivation Function (CK', IK') as specified in 3GPP.33.402.

       CK' || IK' = HMAC-SHA-256(Key, S)
       S = FC || P0 || L0 || P1 || L1 || ... || Pn || Ln
       Key = CK || IK
       FC = 0x20
       P0 = access network identity (3GPP TS 24.302)
       L0 = length of access network identity (2 octets, big endian)
       P1 = SQN xor AK (if AK is not used, AK is treated as 000..0
       L1 = 0x00 0x06
Note
expects keys to contain a AKA_SIM_VECTOR_UMTS.
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 645 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_finalise_checkcode()

ssize_t fr_aka_sim_crypto_finalise_checkcode ( TALLOC_CTX *  ctx,
uint8_t **  out,
fr_aka_sim_checkcode_t checkcode 
)

Write out the final checkcode value.

Parameters
[in]ctxctx to allocate buffer containing the checkcode.
[out]outtalloced buffer containing the checkcode. bytes if MD was SHA1, or 32 bytes if MD was SHA256.
[in,out]checkcodestructure to get final digest from and to tree.
Returns
  • <= 0 on failure.
  • > 0 the number of bytes written to out.

Definition at line 196 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_gsm_kdf_0()

int fr_aka_sim_crypto_gsm_kdf_0 ( fr_aka_sim_keys_t keys)

Key Derivation Function as described in RFC4186 (EAP-SIM) section 7.

       MK     = SHA1(Identity|n*Kc| NONCE_MT| Version List| Selected Version)
       FK     = PRF(MK)
       K_encr = FK[0..127]
       K_aut  = FK[128..255]
       MSK    = FK[256..767]
       EMSK   = FK[768..1279]
Note
expects keys to contain a AKA_SIM_VECTOR_GSM.
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 462 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_init_checkcode()

int fr_aka_sim_crypto_init_checkcode ( TALLOC_CTX *  ctx,
fr_aka_sim_checkcode_t **  checkcode,
EVP_MD const *  md 
)

Initialise checkcode message digest.

Parameters
[in]ctxto allocate checkcode structure in.
[out]checkcodea new checkcode structure.
[in]mdto use when calculating the checkcode, either EVP_sha1(), or EVP_sha256().
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 114 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_kdf_0_reauth()

int fr_aka_sim_crypto_kdf_0_reauth ( fr_aka_sim_keys_t keys)

Key Derivation Function (Fast-Reauthentication) as described in RFC4186/7 (EAP-SIM/AKA) section 7.

       XKEY' = SHA1(Identity|counter|NONCE_S|MK)
       FK    = PRF(XKEY')
       MSK   = FK[0..511]
       EMSK  = FK[512..1023]

Derives new MSK, EMSK, k_aut, k_encr

Use fr_aka_sim_crypto_keys_init_kdf_0_reauth to populate the fr_aka_sim_keys_t structure.

Note
expects keys to contain a populated mk, none_s and counter values.
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 990 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_keys_init_kdf_0_reauth()

void fr_aka_sim_crypto_keys_init_kdf_0_reauth ( fr_aka_sim_keys_t keys,
uint8_t const  mk[static AKA_SIM_MK_SIZE],
uint16_t  counter 
)

Initialise fr_aka_sim_keys_t with EAP-SIM reauthentication data.

Generates a new nonce_s and copies the mk and counter values into the fr_aka_sim_keys_t.

Parameters
[out]keysstructure to populate.
[in]mkfrom original authentication.
[in]counterre-authentication counter.

Definition at line 917 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_keys_init_umts_kdf_1_reauth()

void fr_aka_sim_crypto_keys_init_umts_kdf_1_reauth ( fr_aka_sim_keys_t keys,
uint8_t const  mk[static AKA_PRIME_MK_REAUTH_SIZE],
uint16_t  counter 
)

Initialise fr_aka_sim_keys_t with EAP-AKA['] reauthentication data.

Generates a new nonce_s and copies the mk and counter values into the fr_aka_sim_keys_t.

Parameters
[out]keysstructure to populate.
[in]mkfrom original authentication.
[in]counterre-authentication counter.

Definition at line 947 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_keys_log()

void fr_aka_sim_crypto_keys_log ( request_t request,
fr_aka_sim_keys_t keys 
)

Dump the current state of all keys associated with the EAP SIM session.

Parameters
[in]requestThe current request.
[in]keysSIM keys associated with the session.

Definition at line 1226 of file crypto.c.

+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_sign_packet()

ssize_t fr_aka_sim_crypto_sign_packet ( uint8_t  out[static AKA_SIM_MAC_DIGEST_SIZE],
eap_packet_t eap_packet,
bool  zero_mac,
EVP_MD const *  md,
uint8_t const *  key,
size_t const  key_len,
uint8_t const *  hmac_extra,
size_t const  hmac_extra_len 
)

Calculate the digest value for a packet.

Run a digest over a fake EAP header, the entire SIM packet and any extra HMAC data, writing a truncated (16 byte) digest value to out.

Note
The 16 byte digest field in the packet must have either been zeroed out before this function is called (as it is when encoding data), or zero_mac must be set to true.
This function uses the EVP_* signing functions. Do not be tempted to swap them for the HMAC functions, as the EVP interface may be hardware accelerated but the HMAC interface is purely a software implementation.
Parameters
[out]outWhere to write the digest.
[in]eap_packetto extract header values from.
[in]zero_macAssume the mac field is not zeroed (i.e. received packet) and skip it during mac calculation feeding in 16 zeroed bytes in its place.
[in]mdto use to create the HMAC.
[in]keyto use to sign the packet.
[in]key_lenLength of the key.
[in]hmac_extradata to concatenate with the packet when calculating the HMAC (may be NULL).
[in]hmac_extra_lenLength of hmac_extra (may be zero).
Returns
  • < 0 on failure.
  • 0 if there's no MAC attribute to verify.
  • > 0 the number of bytes written to out.

Definition at line 284 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_umts_kdf_0()

int fr_aka_sim_crypto_umts_kdf_0 ( fr_aka_sim_keys_t keys)

Key Derivation Function as described in RFC4187 (EAP-AKA) section 7.

Note
expects keys to contain a AKA_SIM_VECTOR_UMTS.
       MK     = SHA1(Identity|IK|CK)
       FK     = PRF(MK)
       K_encr = FK[0..127]
       K_aut  = FK[128..255]
       MSK    = FK[256..767]
       EMSK   = FK[768..1279]
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 564 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_umts_kdf_1()

int fr_aka_sim_crypto_umts_kdf_1 ( fr_aka_sim_keys_t keys)

Key Derivation Function as described in RFC 5448 (EAP-AKA') section 3.3.

       MK     = PRF'(IK'|CK',"EAP-AKA'"|Identity)
       K_encr = MK[0..127]
       K_aut  = MK[128..383]
       K_re   = MK[384..639]
       MSK    = MK[640..1151]
       EMSK   = MK[1152..1663]
Note
expects keys to contain a AKA_SIM_VECTOR_UMTS.
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 846 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_umts_kdf_1_reauth()

int fr_aka_sim_crypto_umts_kdf_1_reauth ( fr_aka_sim_keys_t keys)

Key Derivation Function (Fast-Reauthentication) as described in RFC 5448 (EAP-AKA') section 3.3.

       MK   = PRF'(K_re,"EAP-AKA' re-auth"|Identity|counter|NONCE_S)
       MSK  = MK[0..511]
       EMSK = MK[512..1023]
Parameters
[in,out]keysContains the authentication vectors and the buffers to store the result of the derivation.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 1139 of file crypto.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_aka_sim_crypto_update_checkcode()

int fr_aka_sim_crypto_update_checkcode ( fr_aka_sim_checkcode_t checkcode,
eap_packet_t eap_packet 
)

Digest a packet, updating the checkcode.

Call fr_aka_sim_crypto_finalise_checkcode to obtain the final checkcode value.

Parameters
[in,out]checkcodeif *checkcode is NULL, a new checkcode structure will be allocated and the message digest context will be initialised before the provided eap_packet is fed into the digest.
[in]eap_packetto digest.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 152 of file crypto.c.

+ Here is the caller graph for this function:

◆ fr_aka_sim_find_mac()

static int fr_aka_sim_find_mac ( uint8_t const **  out,
uint8_t data,
size_t  data_len 
)
static

Locate the start of the AT_MAC value in the buffer.

Parameters
[out]outThe start of the digest portion of the AT_MAC attribute.
[in]datato search for the AT_MAC in.
[in]data_lensize of the data.
Returns
  • 1 if we couldn't find a MAC.
  • 0 if we found and zeroed out the mac field.
  • -1 if the field was malformed.

Definition at line 222 of file crypto.c.

+ Here is the caller graph for this function:

Variable Documentation

◆ evp_chipher_ctx

_Thread_local EVP_CIPHER_CTX* evp_chipher_ctx
static

Used for every non-persistent EVP_CIPHER operation in this library.

Avoids memory churn allocating and freeing the ctx for each operation.

Definition at line 57 of file crypto.c.