The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
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"
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... | |
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, but these have since been replaced. ande lman. otta wa.on .ca
Definition in file crypto.c.
#define KDF_1_S_REAUTH_STATIC "EAP-AKA' re-auth" |
#define KDF_1_S_STATIC "EAP-AKA'" |
|
static |
|
static |
|
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.
[out] | out | Where to write the output of the PRF. |
[in] | outlen | how many bytes need to be generated. |
[in] | key | for the PRF (K). |
[in] | key_len | Length of key data. |
[in] | in | Data to feed into the PRF (S). |
[in] | in_len | Length of input data. |
Definition at line 773 of file crypto.c.
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.
void aka_sim_crypto_cipher_ctx_free | ( | void | ) |
|
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
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 645 of file crypto.c.
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.
[in] | ctx | ctx to allocate buffer containing the checkcode. |
[out] | out | talloced buffer containing the checkcode. bytes if MD was SHA1, or 32 bytes if MD was SHA256. |
[in,out] | checkcode | structure to get final digest from and to tree. |
Definition at line 196 of file crypto.c.
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]
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 462 of file crypto.c.
int fr_aka_sim_crypto_init_checkcode | ( | TALLOC_CTX * | ctx, |
fr_aka_sim_checkcode_t ** | checkcode, | ||
EVP_MD const * | md | ||
) |
Initialise checkcode message digest.
[in] | ctx | to allocate checkcode structure in. |
[out] | checkcode | a new checkcode structure. |
[in] | md | to use when calculating the checkcode, either EVP_sha1(), or EVP_sha256(). |
Definition at line 114 of file crypto.c.
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.
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 990 of file crypto.c.
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.
[out] | keys | structure to populate. |
[in] | mk | from original authentication. |
[in] | counter | re-authentication counter. |
Definition at line 917 of file crypto.c.
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.
[out] | keys | structure to populate. |
[in] | mk | from original authentication. |
[in] | counter | re-authentication counter. |
Definition at line 947 of file crypto.c.
void fr_aka_sim_crypto_keys_log | ( | request_t * | request, |
fr_aka_sim_keys_t * | keys | ||
) |
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.
[out] | out | Where to write the digest. |
[in] | eap_packet | to extract header values from. |
[in] | zero_mac | Assume 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] | md | to use to create the HMAC. |
[in] | key | to use to sign the packet. |
[in] | key_len | Length of the key. |
[in] | hmac_extra | data to concatenate with the packet when calculating the HMAC (may be NULL). |
[in] | hmac_extra_len | Length of hmac_extra (may be zero). |
Definition at line 284 of file crypto.c.
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.
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]
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 564 of file crypto.c.
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]
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 846 of file crypto.c.
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]
[in,out] | keys | Contains the authentication vectors and the buffers to store the result of the derivation. |
Definition at line 1139 of file crypto.c.
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.
[in,out] | checkcode | if *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_packet | to digest. |
Definition at line 152 of file crypto.c.
Locate the start of the AT_MAC value in the buffer.
[out] | out | The start of the digest portion of the AT_MAC attribute. |
[in] | data | to search for the AT_MAC in. |
[in] | data_len | size of the data. |
Definition at line 222 of file crypto.c.