The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions
crypto.h File Reference

Constants, session state, and crypto declarations for EAP-PSK (RFC 4764) More...

#include <freeradius-devel/eap/base.h>
+ Include dependency graph for crypto.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  eap_psk_session_t
 

Macros

#define EAP_PSK_AK_LEN   16 /* authentication key */
 
#define EAP_PSK_EMSK_LEN   64
 
#define EAP_PSK_FLAGS_FIRST   0x00 /* T=0, first message (server -> peer) */
 
#define EAP_PSK_FLAGS_FOURTH   0xc0 /* T=3, fourth message (peer -> server) */
 
#define EAP_PSK_FLAGS_SECOND   0x40 /* T=1, second message (peer -> server) */
 
#define EAP_PSK_FLAGS_THIRD   0x80 /* T=2, third message (server -> peer) */
 
#define EAP_PSK_HEADER_LEN   (4 + 1 + 1 + EAP_PSK_RAND_LEN)
 
#define EAP_PSK_KDK_LEN   16 /* key-derivation key */
 
#define EAP_PSK_MAC_LEN   16 /* MAC_P and MAC_S (AES-CMAC tags) */
 
#define EAP_PSK_MAX_ID_P_LEN   966
 
#define EAP_PSK_MSK_LEN   64
 
#define EAP_PSK_NONCE_LEN   4 /* the PCHANNEL nonce/counter, on the wire */
 
#define EAP_PSK_PAYLOAD(_r)   (uint8_t)(((_r) & 0x03) << 6) /* R, E=0, Reserved=0 */
 
#define EAP_PSK_PCHANNEL_LEN   (EAP_PSK_NONCE_LEN + EAP_PSK_TAG_LEN + 1)
 
#define EAP_PSK_PSK_LEN   16 /* the pre-shared key */
 
#define EAP_PSK_R(_b)   (((_b) >> 6) & 0x03)
 
#define EAP_PSK_R_CONT   1
 
#define EAP_PSK_R_DONE_FAILURE   3
 
#define EAP_PSK_R_DONE_SUCCESS   2
 
#define EAP_PSK_RAND_LEN   16 /* RAND_S and RAND_P */
 
#define EAP_PSK_T_MASK   0xc0
 
#define EAP_PSK_TAG_LEN   16 /* EAX authentication tag */
 
#define EAP_PSK_TEK_LEN   16 /* transient EAP key */
 

Enumerations

enum  eap_psk_state_t {
  EAP_PSK_STATE_INIT = 0 ,
  EAP_PSK_STATE_IDENTITY_REQUEST_SENT ,
  EAP_PSK_STATE_RESULT_INDICATION_SENT ,
  EAP_PSK_STATE_DONE ,
  EAP_PSK_STATE_FAILED
}
 

Functions

int eap_psk_derive_ak_kdk (uint8_t ak[static EAP_PSK_AK_LEN], uint8_t kdk[static EAP_PSK_KDK_LEN], uint8_t const psk[static EAP_PSK_PSK_LEN])
 Key setup: derive AK (counter 1) and KDK (counter 2) from the PSK.
 
int eap_psk_derive_keys (uint8_t tek[static EAP_PSK_TEK_LEN], uint8_t msk[static EAP_PSK_MSK_LEN], uint8_t emsk[static EAP_PSK_EMSK_LEN], uint8_t const kdk[static EAP_PSK_KDK_LEN], uint8_t const rand_p[static EAP_PSK_RAND_LEN])
 Session-key derivation: expand RAND_P under KDK into nine output blocks.
 
int eap_psk_mac_p (uint8_t mac_p[static EAP_PSK_MAC_LEN], uint8_t const ak[static EAP_PSK_AK_LEN], uint8_t const *id_p, size_t id_p_len, uint8_t const *id_s, size_t id_s_len, uint8_t const rand_s[static EAP_PSK_RAND_LEN], uint8_t const rand_p[static EAP_PSK_RAND_LEN])
 Compute MAC_P = CMAC-AES-128(AK, ID_P || ID_S || RAND_S || RAND_P)
 
int eap_psk_mac_s (uint8_t mac_s[static EAP_PSK_MAC_LEN], uint8_t const ak[static EAP_PSK_AK_LEN], uint8_t const *id_s, size_t id_s_len, uint8_t const rand_p[static EAP_PSK_RAND_LEN])
 Compute MAC_S = CMAC-AES-128(AK, ID_S || RAND_P)
 
int eap_psk_pchannel_decrypt (uint8_t *plain, uint8_t const tek[static EAP_PSK_TEK_LEN], uint32_t nonce, uint8_t const *header, size_t header_len, uint8_t const *cipher, size_t cipher_len, uint8_t const tag[static EAP_PSK_TAG_LEN])
 EAX decrypt-and-verify for the protected channel (RFC 4764 Section 3.3)
 
int eap_psk_pchannel_encrypt (uint8_t *cipher, uint8_t tag[static EAP_PSK_TAG_LEN], uint8_t const tek[static EAP_PSK_TEK_LEN], uint32_t nonce, uint8_t const *header, size_t header_len, uint8_t const *plain, size_t plain_len)
 EAX encrypt for the protected channel (RFC 4764 Section 3.3)
 

Detailed Description

Constants, session state, and crypto declarations for EAP-PSK (RFC 4764)

Id
9b05bf9aac315a6593bdb0fdde778ea4442f119d

Definition in file crypto.h.


Data Structure Documentation

◆ eap_psk_session_t

struct eap_psk_session_t

Definition at line 98 of file crypto.h.

+ Collaboration diagram for eap_psk_session_t:
Data Fields
uint8_t emsk[EAP_PSK_EMSK_LEN]
uint8_t * id_p ID_P the peer asserted in the second message.
size_t id_p_len
char * id_s ID_S actually sent in the first message.
uint8_t mac_p[EAP_PSK_MAC_LEN] As received, verified once the PSK is known.
uint8_t msk[EAP_PSK_MSK_LEN]
uint8_t rand_p[EAP_PSK_RAND_LEN]
uint8_t rand_s[EAP_PSK_RAND_LEN]
unlang_result_t section_result Result of the last policy section.
eap_psk_state_t state
uint8_t tek[EAP_PSK_TEK_LEN]

Macro Definition Documentation

◆ EAP_PSK_AK_LEN

#define EAP_PSK_AK_LEN   16 /* authentication key */

Definition at line 37 of file crypto.h.

◆ EAP_PSK_EMSK_LEN

#define EAP_PSK_EMSK_LEN   64

Definition at line 41 of file crypto.h.

◆ EAP_PSK_FLAGS_FIRST

#define EAP_PSK_FLAGS_FIRST   0x00 /* T=0, first message (server -> peer) */

Definition at line 50 of file crypto.h.

◆ EAP_PSK_FLAGS_FOURTH

#define EAP_PSK_FLAGS_FOURTH   0xc0 /* T=3, fourth message (peer -> server) */

Definition at line 53 of file crypto.h.

◆ EAP_PSK_FLAGS_SECOND

#define EAP_PSK_FLAGS_SECOND   0x40 /* T=1, second message (peer -> server) */

Definition at line 51 of file crypto.h.

◆ EAP_PSK_FLAGS_THIRD

#define EAP_PSK_FLAGS_THIRD   0x80 /* T=2, third message (server -> peer) */

Definition at line 52 of file crypto.h.

◆ EAP_PSK_HEADER_LEN

#define EAP_PSK_HEADER_LEN   (4 + 1 + 1 + EAP_PSK_RAND_LEN)

Definition at line 78 of file crypto.h.

◆ EAP_PSK_KDK_LEN

#define EAP_PSK_KDK_LEN   16 /* key-derivation key */

Definition at line 38 of file crypto.h.

◆ EAP_PSK_MAC_LEN

#define EAP_PSK_MAC_LEN   16 /* MAC_P and MAC_S (AES-CMAC tags) */

Definition at line 35 of file crypto.h.

◆ EAP_PSK_MAX_ID_P_LEN

#define EAP_PSK_MAX_ID_P_LEN   966

Definition at line 83 of file crypto.h.

◆ EAP_PSK_MSK_LEN

#define EAP_PSK_MSK_LEN   64

Definition at line 40 of file crypto.h.

◆ EAP_PSK_NONCE_LEN

#define EAP_PSK_NONCE_LEN   4 /* the PCHANNEL nonce/counter, on the wire */

Definition at line 42 of file crypto.h.

◆ EAP_PSK_PAYLOAD

#define EAP_PSK_PAYLOAD (   _r)    (uint8_t)(((_r) & 0x03) << 6) /* R, E=0, Reserved=0 */

Definition at line 65 of file crypto.h.

◆ EAP_PSK_PCHANNEL_LEN

#define EAP_PSK_PCHANNEL_LEN   (EAP_PSK_NONCE_LEN + EAP_PSK_TAG_LEN + 1)

Definition at line 71 of file crypto.h.

◆ EAP_PSK_PSK_LEN

#define EAP_PSK_PSK_LEN   16 /* the pre-shared key */

Definition at line 36 of file crypto.h.

◆ EAP_PSK_R

#define EAP_PSK_R (   _b)    (((_b) >> 6) & 0x03)

Definition at line 64 of file crypto.h.

◆ EAP_PSK_R_CONT

#define EAP_PSK_R_CONT   1

Definition at line 60 of file crypto.h.

◆ EAP_PSK_R_DONE_FAILURE

#define EAP_PSK_R_DONE_FAILURE   3

Definition at line 62 of file crypto.h.

◆ EAP_PSK_R_DONE_SUCCESS

#define EAP_PSK_R_DONE_SUCCESS   2

Definition at line 61 of file crypto.h.

◆ EAP_PSK_RAND_LEN

#define EAP_PSK_RAND_LEN   16 /* RAND_S and RAND_P */

Definition at line 34 of file crypto.h.

◆ EAP_PSK_T_MASK

#define EAP_PSK_T_MASK   0xc0

Definition at line 49 of file crypto.h.

◆ EAP_PSK_TAG_LEN

#define EAP_PSK_TAG_LEN   16 /* EAX authentication tag */

Definition at line 43 of file crypto.h.

◆ EAP_PSK_TEK_LEN

#define EAP_PSK_TEK_LEN   16 /* transient EAP key */

Definition at line 39 of file crypto.h.

Enumeration Type Documentation

◆ eap_psk_state_t

Enumerator
EAP_PSK_STATE_INIT 
EAP_PSK_STATE_IDENTITY_REQUEST_SENT 
EAP_PSK_STATE_RESULT_INDICATION_SENT 
EAP_PSK_STATE_DONE 
EAP_PSK_STATE_FAILED 

Definition at line 85 of file crypto.h.

Function Documentation

◆ eap_psk_derive_ak_kdk()

int eap_psk_derive_ak_kdk ( uint8_t  ak[static EAP_PSK_AK_LEN],
uint8_t  kdk[static EAP_PSK_KDK_LEN],
uint8_t const  psk[static EAP_PSK_PSK_LEN] 
)

Key setup: derive AK (counter 1) and KDK (counter 2) from the PSK.

Expands a constant all-zero input block under the PSK using the modified counter mode. See RFC 4764 Section 3.1, Figure 3.

Parameters
[out]akthe derived authentication key.
[out]kdkthe derived key-derivation key.
[in]pskthe 16-byte pre-shared key.
Returns
  • 0 on success.
  • -1 on OpenSSL failure.

Definition at line 164 of file crypto.c.

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

◆ eap_psk_derive_keys()

int eap_psk_derive_keys ( uint8_t  tek[static EAP_PSK_TEK_LEN],
uint8_t  msk[static EAP_PSK_MSK_LEN],
uint8_t  emsk[static EAP_PSK_EMSK_LEN],
uint8_t const  kdk[static EAP_PSK_KDK_LEN],
uint8_t const  rand_p[static EAP_PSK_RAND_LEN] 
)

Session-key derivation: expand RAND_P under KDK into nine output blocks.

Block 1 is the TEK, blocks 2..5 are the MSK, and blocks 6..9 are the EMSK. See RFC 4764 Section 3.2, Figure 7.

Parameters
[out]tekthe transient EAP key, used for the protected channel.
[out]mskthe 64-byte master session key.
[out]emskthe 64-byte extended master session key.
[in]kdkthe key-derivation key from eap_psk_derive_ak_kdk().
[in]rand_pthe peer's 16-byte nonce.
Returns
  • 0 on success.
  • -1 on OpenSSL failure.

Definition at line 194 of file crypto.c.

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

◆ eap_psk_mac_p()

int eap_psk_mac_p ( uint8_t  mac_p[static EAP_PSK_MAC_LEN],
uint8_t const  ak[static EAP_PSK_AK_LEN],
uint8_t const *  id_p,
size_t  id_p_len,
uint8_t const *  id_s,
size_t  id_s_len,
uint8_t const  rand_s[static EAP_PSK_RAND_LEN],
uint8_t const  rand_p[static EAP_PSK_RAND_LEN] 
)

Compute MAC_P = CMAC-AES-128(AK, ID_P || ID_S || RAND_S || RAND_P)

The peer proves possession of the PSK with MAC_P in the second message. See RFC 4764 Section 5.2.

Parameters
[out]mac_pthe computed 16-byte MAC.
[in]akthe authentication key.
[in]id_pthe peer's NAI. May not be NULL terminated.
[in]id_p_lenlength of id_p.
[in]id_sthe server's NAI.
[in]id_s_lenlength of id_s.
[in]rand_sthe server's nonce.
[in]rand_pthe peer's nonce.
Returns
  • 0 on success.
  • -1 on OpenSSL failure.

Definition at line 283 of file crypto.c.

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

◆ eap_psk_mac_s()

int eap_psk_mac_s ( uint8_t  mac_s[static EAP_PSK_MAC_LEN],
uint8_t const  ak[static EAP_PSK_AK_LEN],
uint8_t const *  id_s,
size_t  id_s_len,
uint8_t const  rand_p[static EAP_PSK_RAND_LEN] 
)

Compute MAC_S = CMAC-AES-128(AK, ID_S || RAND_P)

The server proves possession of the PSK with MAC_S in the third message. See RFC 4764 Section 5.3.

Parameters
[out]mac_sthe computed 16-byte MAC.
[in]akthe authentication key.
[in]id_sthe server's NAI.
[in]id_s_lenlength of id_s.
[in]rand_pthe peer's nonce.
Returns
  • 0 on success.
  • -1 on OpenSSL failure.

Definition at line 311 of file crypto.c.

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

◆ eap_psk_pchannel_decrypt()

int eap_psk_pchannel_decrypt ( uint8_t plain,
uint8_t const  tek[static EAP_PSK_TEK_LEN],
uint32_t  nonce,
uint8_t const *  header,
size_t  header_len,
uint8_t const *  cipher,
size_t  cipher_len,
uint8_t const  tag[static EAP_PSK_TAG_LEN] 
)

EAX decrypt-and-verify for the protected channel (RFC 4764 Section 3.3)

Recomputes the tag over the received ciphertext and header, and compares the result (in constant time) against the received tag. Only if the tags match is the ciphertext decrypted.

Parameters
[out]plainreceives cipher_len bytes of plaintext.
[in]tekthe transient EAP key.
[in]noncethe 4-byte PCHANNEL counter (1 for the fourth message).
[in]headerthe EAX header H to authenticate.
[in]header_lenlength of header.
[in]cipherthe ciphertext to verify and decrypt.
[in]cipher_lenlength of cipher.
[in]tagthe received 16-byte authentication tag.
Returns
  • 0 if the tag is valid and the plaintext was recovered.
  • -1 on a bad tag or an OpenSSL error.

Definition at line 439 of file crypto.c.

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

◆ eap_psk_pchannel_encrypt()

int eap_psk_pchannel_encrypt ( uint8_t cipher,
uint8_t  tag[static EAP_PSK_TAG_LEN],
uint8_t const  tek[static EAP_PSK_TEK_LEN],
uint32_t  nonce,
uint8_t const *  header,
size_t  header_len,
uint8_t const *  plain,
size_t  plain_len 
)

EAX encrypt for the protected channel (RFC 4764 Section 3.3)

Computes:

 N' = OMAC^0(nonce_block)
 H' = OMAC^1(header)
 C  = CTR_{N'}(plain)
 C' = OMAC^2(C)
 tag = N' XOR H' XOR C'

Either the plaintext or its length may be zero (EAP-PSK only ever protects a single byte, but the code does not rely on that).

Parameters
[out]cipherreceives plain_len bytes of ciphertext.
[out]tagreceives the 16-byte authentication tag.
[in]tekthe transient EAP key.
[in]noncethe 4-byte PCHANNEL counter (0 for the third message).
[in]headerthe EAX header H to authenticate.
[in]header_lenlength of header.
[in]plainthe plaintext to encrypt.
[in]plain_lenlength of plain.
Returns
  • 0 on success.
  • -1 on OpenSSL failure.

Definition at line 395 of file crypto.c.

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