The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
crypto.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 7b7aa96359b1ecf54a963e6b1326ce9ad5aef1a4 $
19  * @file lib/eap/crypto.c
20  * @brief MPPE key calculation API
21  *
22  * @author Henrik Eriksson (henriken@axis.com)
23  * @author Lars Viklund (larsv@axis.com)
24  *
25  * @copyright 2002 Axis Communications AB
26  * @copyright 2006 The FreeRADIUS server project
27  */
28 
29 RCSID("$Id: 7b7aa96359b1ecf54a963e6b1326ce9ad5aef1a4 $")
30 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
31 
32 #define __STDC_WANT_LIB_EXT1__ 1
33 #include <string.h>
34 
35 #include <freeradius-devel/util/sha1.h>
36 #include <freeradius-devel/tls/base.h>
37 #include <freeradius-devel/tls/log.h>
38 
39 #include "tls.h"
40 #include "base.h"
41 #include "attrs.h"
42 
43 #include <openssl/hmac.h>
44 
45 /** Initialize the PRF label fields
46  *
47  */
49  char const *keying_prf_label, size_t keying_prf_label_len)
50 {
51 #ifdef TLS1_3_VERSION
52  eap_tls_session_t *eap_tls_session = talloc_get_type_abort(eap_session->opaque, eap_tls_session_t);
53 
54  if (eap_tls_session->tls_session->info.version == TLS1_3_VERSION) {
55  prf_label->keying_prf_label = "EXPORTER_EAP_TLS_Key_Material";
56  prf_label->keying_prf_label_len = sizeof("EXPORTER_EAP_TLS_Key_Material") - 1;
57 
58  prf_label->sessid_prf_label = "EXPORTER_EAP_TLS_Method-Id";
59  prf_label->sessid_prf_label_len = sizeof("EXPORTER_EAP_TLS_Method-Id") - 1;
60 
61  prf_label->context[0] = eap_session->type;
62  prf_label->context_len = 1;
63  prf_label->use_context = 1;
64  return;
65  }
66 #endif
67 
68  prf_label->keying_prf_label = keying_prf_label;
69  prf_label->keying_prf_label_len = keying_prf_label_len;
70 
71  prf_label->sessid_prf_label = NULL;
72  prf_label->sessid_prf_label_len = 0;
73 
74  prf_label->context[0] = 0;
75  prf_label->context_len = 0;
76  prf_label->use_context = 0;
77 }
78 
79 
80 #define EAP_TLS_MPPE_KEY_LEN 32
81 
82 /** Generate keys according to RFC 5216 and add to the reply
83  *
84  */
85 int eap_crypto_mppe_keys(request_t *request, SSL *ssl, eap_tls_prf_label_t *prf_label)
86 {
88  uint8_t *p;
89 
90  if (!prf_label->keying_prf_label) return 0;
91 
92  if (SSL_export_keying_material(ssl, out, sizeof(out),
93  prf_label->keying_prf_label,
94  prf_label->keying_prf_label_len,
95  prf_label->context,
96  prf_label->context_len,
97  prf_label->use_context) != 1) {
98  fr_tls_log(request, "Failed generating MPPE keys");
99  return -1;
100  }
101 
102  if (RDEBUG_ENABLED3) {
103  uint8_t random[SSL3_RANDOM_SIZE];
104  size_t random_len;
105  uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
106  size_t master_key_len;
107 
108  RDEBUG3("Key Derivation Function input");
109  RINDENT();
110  RDEBUG3("prf label : %s", prf_label->keying_prf_label);
111  master_key_len = SSL_SESSION_get_master_key(SSL_get_session(ssl), master_key, sizeof(master_key));
112  RDEBUG3("master session key : %pH", fr_box_octets(master_key, master_key_len));
113  random_len = SSL_get_client_random(ssl, random, SSL3_RANDOM_SIZE);
114  RDEBUG3("client random : %pH", fr_box_octets(random, random_len));
115  random_len = SSL_get_server_random(ssl, random, SSL3_RANDOM_SIZE);
116  RDEBUG3("server random : %pH", fr_box_octets(random, random_len));
117  REXDENT();
118  }
119 
120  RDEBUG2("Adding session keys");
121  p = out;
125 
126  eap_add_reply(request, attr_eap_msk, out, 64);
127  eap_add_reply(request, attr_eap_emsk, out + 64, 64);
128 
129  return 0;
130 }
131 
132 int eap_crypto_tls_session_id(TALLOC_CTX *ctx,
133  request_t *request, SSL *ssl, eap_tls_prf_label_t *prf_label,
135 {
136  uint8_t *buff = NULL, *p;
137 
138  *out = NULL;
139 
140  if (!prf_label->sessid_prf_label) goto random_based_session_id;
141 
142  switch (SSL_SESSION_get_protocol_version(SSL_get_session(ssl))) {
143  case SSL2_VERSION: /* Should never happen */
144  case SSL3_VERSION: /* Should never happen */
145  return - 1;
146 
147  case TLS1_VERSION: /* No Method ID */
148  case TLS1_1_VERSION: /* No Method ID */
149  case TLS1_2_VERSION: /* No Method ID */
150  random_based_session_id:
151  MEM(buff = p = talloc_array(ctx, uint8_t, sizeof(eap_type) + (2 * SSL3_RANDOM_SIZE)));
152  *p++ = eap_type;
153 
154  SSL_get_client_random(ssl, p, SSL3_RANDOM_SIZE);
155  p += SSL3_RANDOM_SIZE;
156  SSL_get_server_random(ssl, p, SSL3_RANDOM_SIZE);
157  break;
158 
159  /*
160  * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id", "", 64)
161  * Session-Id = <EAP-Type> || Method-Id
162  */
163  case TLS1_3_VERSION:
164  default:
165  {
166  MEM(buff = p = talloc_array(ctx, uint8_t, sizeof(eap_type) + 64));
167  *p++ = eap_type;
168  if (SSL_export_keying_material(ssl, p, 64,
169  prf_label->sessid_prf_label,
170  prf_label->sessid_prf_label_len,
171  prf_label->context,
172  prf_label->context_len,
173  prf_label->use_context) != 1) {
174  fr_tls_log(request, "Failed generating TLS session ID");
175  return -1;
176  }
177  }
178  break;
179  }
180  *out = buff;
181 
182  return 0;
183 }
#define USES_APPLE_DEPRECATED_API
Definition: build.h:468
#define RCSID(id)
Definition: build.h:481
void eap_crypto_prf_label_init(eap_tls_prf_label_t *prf_label, eap_session_t *eap_session, char const *keying_prf_label, size_t keying_prf_label_len)
Initialize the PRF label fields.
Definition: crypto.c:48
int eap_crypto_mppe_keys(request_t *request, SSL *ssl, eap_tls_prf_label_t *prf_label)
Generate keys according to RFC 5216 and add to the reply.
Definition: crypto.c:85
#define EAP_TLS_MPPE_KEY_LEN
Definition: crypto.c:80
int eap_crypto_tls_session_id(TALLOC_CTX *ctx, request_t *request, SSL *ssl, eap_tls_prf_label_t *prf_label, uint8_t **out, uint8_t eap_type)
Definition: crypto.c:132
eap_type
Definition: types.h:44
HIDDEN fr_dict_attr_t const * attr_ms_mppe_send_key
Definition: base.c:99
HIDDEN fr_dict_attr_t const * attr_ms_mppe_recv_key
Definition: base.c:100
HIDDEN fr_dict_attr_t const * attr_eap_msk
Definition: base.c:95
HIDDEN fr_dict_attr_t const * attr_eap_emsk
Definition: base.c:96
void eap_add_reply(request_t *request, fr_dict_attr_t const *da, uint8_t const *value, int len)
Definition: base.c:381
void * opaque
Opaque data used by EAP methods.
Definition: session.h:62
eap_type_t type
EAP method number.
Definition: session.h:49
Tracks the progress of a single session of any EAP method.
Definition: session.h:40
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:443
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition: log.h:335
#define RDEBUG3(fmt,...)
Definition: log.h:343
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:430
unsigned char uint8_t
Definition: merged_model.c:30
VQP attributes.
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
Generic EAP over TLS API.
fr_tls_session_t * tls_session
TLS session used to authenticate peer or tunnel sensitive data.
Definition: tls.h:129
size_t keying_prf_label_len
length of the keying PRF label.
Definition: tls.h:157
char const * keying_prf_label
PRF label to use for generating keying material.
Definition: tls.h:155
size_t context_len
length of the context
Definition: tls.h:164
uint8_t context[1]
for TLS 1.3 context, is the EAP Type code
Definition: tls.h:163
char const * sessid_prf_label
PRF label to use when generating the session ID.
Definition: tls.h:159
int use_context
for SSL_export_keying_material().
Definition: tls.h:166
size_t sessid_prf_label_len
Length of the session ID PRF label.
Definition: tls.h:161
Tracks the state of an EAP-TLS session.
Definition: tls.h:126
Master include file to access all functions and structures in the library.
static size_t char ** out
Definition: value.h:997
#define fr_box_octets(_val, _len)
Definition: value.h:288