aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/crypto/tls.h8
-rw-r--r--src/crypto/tls_gnutls.c11
-rw-r--r--src/crypto/tls_internal.c5
-rw-r--r--src/crypto/tls_none.c3
-rw-r--r--src/crypto/tls_openssl.c6
-rw-r--r--src/crypto/tls_wolfssl.c5
-rw-r--r--src/eap_peer/eap_peap.c1
-rw-r--r--src/eap_peer/eap_tls.c1
-rw-r--r--src/eap_peer/eap_tls_common.c13
-rw-r--r--src/eap_peer/eap_tls_common.h3
-rw-r--r--src/eap_peer/eap_ttls.c4
-rw-r--r--src/eap_server/eap_server_peap.c6
-rw-r--r--src/eap_server/eap_server_tls.c2
-rw-r--r--src/eap_server/eap_server_tls_common.c9
-rw-r--r--src/eap_server/eap_server_ttls.c6
-rw-r--r--src/eap_server/eap_tls_common.h3
16 files changed, 62 insertions, 24 deletions
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 6cc9241..9463f58 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -370,15 +370,21 @@ int __must_check tls_connection_get_random(void *tls_ctx,
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @label: Label (e.g., description of the key) for PRF
+ * @context: Optional extra upper-layer context (max len 2^16)
+ * @context_len: The length of the context value
* @out: Buffer for output data from TLS-PRF
* @out_len: Length of the output buffer
* Returns: 0 on success, -1 on failure
*
- * Exports keying material using the mechanism described in RFC 5705.
+ * Exports keying material using the mechanism described in RFC 5705. If
+ * context is %NULL, context is not provided; otherwise, context is provided
+ * (including the case of empty context with context_len == 0).
*/
int __must_check tls_connection_export_key(void *tls_ctx,
struct tls_connection *conn,
const char *label,
+ const u8 *context,
+ size_t context_len,
u8 *out, size_t out_len);
/**
diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c
index 73e80f3..ccd2884 100644
--- a/src/crypto/tls_gnutls.c
+++ b/src/crypto/tls_gnutls.c
@@ -898,14 +898,23 @@ int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
if (conn == NULL || conn->session == NULL)
return -1;
+#if GNUTLS_VERSION_NUMBER >= 0x030404
+ return gnutls_prf_rfc5705(conn->session, os_strlen(label), label,
+ context_len, (const char *) context,
+ out_len, (char *) out);
+#else /* 3.4.4 */
+ if (context)
+ return -1;
return gnutls_prf(conn->session, os_strlen(label), label,
0 /* client_random first */, 0, NULL, out_len,
(char *) out);
+#endif /* 3.4.4 */
}
diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c
index 2876630..50a7b30 100644
--- a/src/crypto/tls_internal.c
+++ b/src/crypto/tls_internal.c
@@ -452,8 +452,11 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
+ if (context)
+ return -1;
return tls_connection_prf(tls_ctx, conn, label, 0, 0, out, out_len);
}
diff --git a/src/crypto/tls_none.c b/src/crypto/tls_none.c
index 108e9aa..6d6fb0c 100644
--- a/src/crypto/tls_none.c
+++ b/src/crypto/tls_none.c
@@ -94,7 +94,8 @@ int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
return -1;
}
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index b8d0556..fc55518 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -3908,11 +3908,13 @@ static int openssl_get_keyblock_size(SSL *ssl)
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
if (!conn ||
SSL_export_keying_material(conn->ssl, out, out_len, label,
- os_strlen(label), NULL, 0, 0) != 1)
+ os_strlen(label), context, context_len,
+ context != NULL) != 1)
return -1;
return 0;
}
diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
index 39a24b3..41fc946 100644
--- a/src/crypto/tls_wolfssl.c
+++ b/src/crypto/tls_wolfssl.c
@@ -1973,8 +1973,11 @@ int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
+ if (context)
+ return -1;
if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
return -1;
return 0;
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 650bea6..8dcf7cc 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -1084,6 +1084,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
"key derivation", label);
data->key_data =
eap_peer_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (data->key_data) {
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index cb74702..ffea9d2 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -198,6 +198,7 @@ static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data,
eap_tls_free_key(data);
data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (data->key_data) {
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 1ee01a2..cb94c45 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -349,6 +349,8 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @data: Data for TLS processing
* @label: Label string for deriving the keys, e.g., "client EAP encryption"
+ * @context: Optional extra upper-layer context (max len 2^16)
+ * @context_len: The length of the context value
* @len: Length of the key material to generate (usually 64 for MSK)
* Returns: Pointer to allocated key on success or %NULL on failure
*
@@ -357,9 +359,12 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
* different label to bind the key usage into the generated material.
*
* The caller is responsible for freeing the returned buffer.
+ *
+ * Note: To provide the RFC 5705 context, the context variable must be non-NULL.
*/
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len)
+ const char *label, const u8 *context,
+ size_t context_len, size_t len)
{
u8 *out;
@@ -367,8 +372,8 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
if (out == NULL)
return NULL;
- if (tls_connection_export_key(data->ssl_ctx, data->conn, label, out,
- len)) {
+ if (tls_connection_export_key(data->ssl_ctx, data->conn, label,
+ context, context_len, out, len)) {
os_free(out);
return NULL;
}
@@ -409,7 +414,7 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
if (!id)
return NULL;
method_id = eap_peer_tls_derive_key(
- sm, data, "EXPORTER_EAP_TLS_Method-Id", 64);
+ sm, data, "EXPORTER_EAP_TLS_Method-Id", NULL, 0, 64);
if (!method_id) {
os_free(id);
return NULL;
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 306e6a9..5f82529 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -99,7 +99,8 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
struct eap_peer_config *config, u8 eap_type);
void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len);
+ const char *label, const u8 *context,
+ size_t context_len, size_t len);
u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
struct eap_ssl_data *data, u8 eap_type,
size_t *len);
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 5d26701..1c8dbe2 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -271,6 +271,7 @@ static int eap_ttls_v0_derive_key(struct eap_sm *sm,
eap_ttls_free_key(data);
data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
"ttls keying material",
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (!data->key_data) {
@@ -303,7 +304,8 @@ static int eap_ttls_v0_derive_key(struct eap_sm *sm,
static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
- return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
+ return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge",
+ NULL, 0, len);
}
#endif /* CONFIG_FIPS */
diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c
index 3d334a0..92c0e5e 100644
--- a/src/eap_server/eap_server_peap.c
+++ b/src/eap_server/eap_server_peap.c
@@ -331,7 +331,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
* phase 1 of PEAP (based on TLS).
*/
tk = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption",
- EAP_TLS_KEY_LEN);
+ NULL, 0, EAP_TLS_KEY_LEN);
if (tk == NULL)
return -1;
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
@@ -1333,7 +1333,7 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
/* TODO: PEAPv1 - different label in some cases */
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
+ "client EAP encryption", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN);
@@ -1363,7 +1363,7 @@ static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
/* TODO: PEAPv1 - different label in some cases */
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
+ "client EAP encryption", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_server_tls.c b/src/eap_server/eap_server_tls.c
index 13d2349..357e72a 100644
--- a/src/eap_server/eap_server_tls.c
+++ b/src/eap_server/eap_server_tls.c
@@ -331,6 +331,7 @@ static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len)
else
label = "client EAP encryption";
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
*len = EAP_TLS_KEY_LEN;
@@ -359,6 +360,7 @@ static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
else
label = "client EAP encryption";
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_malloc(EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c
index 4ba7c24..0eca0ff 100644
--- a/src/eap_server/eap_server_tls_common.c
+++ b/src/eap_server/eap_server_tls_common.c
@@ -107,7 +107,8 @@ void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len)
+ const char *label, const u8 *context,
+ size_t context_len, size_t len)
{
u8 *out;
@@ -115,8 +116,8 @@ u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
if (out == NULL)
return NULL;
- if (tls_connection_export_key(sm->ssl_ctx, data->conn, label, out,
- len)) {
+ if (tls_connection_export_key(sm->ssl_ctx, data->conn, label,
+ context, context_len, out, len)) {
os_free(out);
return NULL;
}
@@ -157,7 +158,7 @@ u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
if (!id)
return NULL;
method_id = eap_server_tls_derive_key(
- sm, data, "EXPORTER_EAP_TLS_Method-Id", 64);
+ sm, data, "EXPORTER_EAP_TLS_Method-Id", NULL, 0, 64);
if (!method_id) {
os_free(id);
return NULL;
diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c
index b14996b..52bff8a 100644
--- a/src/eap_server/eap_server_ttls.c
+++ b/src/eap_server/eap_server_ttls.c
@@ -332,7 +332,7 @@ static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
- len);
+ NULL, 0, len);
}
@@ -1268,7 +1268,7 @@ static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
return NULL;
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "ttls keying material",
+ "ttls keying material", NULL, 0,
EAP_TLS_KEY_LEN);
if (eapKeyData) {
*len = EAP_TLS_KEY_LEN;
@@ -1310,7 +1310,7 @@ static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
return NULL;
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "ttls keying material",
+ "ttls keying material", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_malloc(EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_tls_common.h b/src/eap_server/eap_tls_common.h
index 31f6e72..0b04983 100644
--- a/src/eap_server/eap_tls_common.h
+++ b/src/eap_server/eap_tls_common.h
@@ -78,7 +78,8 @@ int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
int verify_peer, int eap_type);
void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len);
+ const char *label, const u8 *context,
+ size_t context_len, size_t len);
u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
struct eap_ssl_data *data, u8 eap_type,
size_t *len);