diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 9a6db909d..0cb68ba97 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3338,6 +3338,15 @@ struct wpa_driver_ops { */ int (*enable_protect_frames)(void *priv, Boolean enabled); + /** + * enable_encrypt - Set encryption status + * @priv: Private driver interface data + * @enabled: TRUE = encrypt outgoing traffic + * FALSE = integrity-only protection on outgoing traffic + * Returns: 0 on success, -1 on failure (or if not supported) + */ + int (*enable_encrypt)(void *priv, Boolean enabled); + /** * set_replay_protect - Set replay protect status and window size * @priv: Private driver interface data diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c index e294e6466..360fcd3f5 100644 --- a/src/pae/ieee802_1x_cp.c +++ b/src/pae/ieee802_1x_cp.c @@ -159,6 +159,7 @@ SM_STATE(CP, ALLOWED) secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); secy_cp_control_protect_frames(sm->kay, sm->protect_frames); + secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); } @@ -177,6 +178,7 @@ SM_STATE(CP, AUTHENTICATED) secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); secy_cp_control_protect_frames(sm->kay, sm->protect_frames); + secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); } @@ -203,6 +205,7 @@ SM_STATE(CP, SECURED) secy_cp_control_confidentiality_offset(sm->kay, sm->confidentiality_offset); secy_cp_control_protect_frames(sm->kay, sm->protect_frames); + secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); } @@ -466,6 +469,7 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay) wpa_printf(MSG_DEBUG, "CP: state machine created"); secy_cp_control_protect_frames(sm->kay, sm->protect_frames); + secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); secy_cp_control_validate_frames(sm->kay, sm->validate_frames); secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h index 618e45b81..fb49f6206 100644 --- a/src/pae/ieee802_1x_kay.h +++ b/src/pae/ieee802_1x_kay.h @@ -142,6 +142,7 @@ struct ieee802_1x_kay_ctx { int (*macsec_deinit)(void *ctx); int (*macsec_get_capability)(void *priv, enum macsec_cap *cap); int (*enable_protect_frames)(void *ctx, Boolean enabled); + int (*enable_encrypt)(void *ctx, Boolean enabled); int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window); int (*set_current_cipher_suite)(void *ctx, u64 cs); int (*enable_controlled_port)(void *ctx, Boolean enabled); diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c index b1a9d223f..ab5339bb2 100644 --- a/src/pae/ieee802_1x_secy_ops.c +++ b/src/pae/ieee802_1x_secy_ops.c @@ -45,6 +45,26 @@ int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean enabled) } +int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, Boolean enabled) +{ + struct ieee802_1x_kay_ctx *ops; + + if (!kay) { + wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); + return -1; + } + + ops = kay->ctx; + if (!ops || !ops->enable_encrypt) { + wpa_printf(MSG_ERROR, + "KaY: secy enable_encrypt operation not supported"); + return -1; + } + + return ops->enable_encrypt(ops->ctx, enabled); +} + + int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean enabled, u32 win) { struct ieee802_1x_kay_ctx *ops; diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h index 477120b1f..9fb29c3dd 100644 --- a/src/pae/ieee802_1x_secy_ops.h +++ b/src/pae/ieee802_1x_secy_ops.h @@ -21,6 +21,7 @@ int secy_deinit_macsec(struct ieee802_1x_kay *kay); int secy_cp_control_validate_frames(struct ieee802_1x_kay *kay, enum validate_frames vf); int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean flag); +int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, Boolean enabled); int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean flag, u32 win); int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs); int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay, diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index c9bb20d90..cf0855647 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -731,6 +731,14 @@ static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s, return wpa_s->driver->enable_protect_frames(wpa_s->drv_priv, enabled); } +static inline int wpa_drv_enable_encrypt(struct wpa_supplicant *wpa_s, + Boolean enabled) +{ + if (!wpa_s->driver->enable_encrypt) + return -1; + return wpa_s->driver->enable_encrypt(wpa_s->drv_priv, enabled); +} + static inline int wpa_drv_set_replay_protect(struct wpa_supplicant *wpa_s, Boolean enabled, u32 window) { diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c index 6343154dd..2ff48954b 100644 --- a/wpa_supplicant/wpas_kay.c +++ b/wpa_supplicant/wpas_kay.c @@ -50,6 +50,12 @@ static int wpas_enable_protect_frames(void *wpa_s, Boolean enabled) } +static int wpas_enable_encrypt(void *wpa_s, Boolean enabled) +{ + return wpa_drv_enable_encrypt(wpa_s, enabled); +} + + static int wpas_set_replay_protect(void *wpa_s, Boolean enabled, u32 window) { return wpa_drv_set_replay_protect(wpa_s, enabled, window); @@ -206,6 +212,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) kay_ctx->macsec_deinit = wpas_macsec_deinit; kay_ctx->macsec_get_capability = wpas_macsec_get_capability; kay_ctx->enable_protect_frames = wpas_enable_protect_frames; + kay_ctx->enable_encrypt = wpas_enable_encrypt; kay_ctx->set_replay_protect = wpas_set_replay_protect; kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite; kay_ctx->enable_controlled_port = wpas_enable_controlled_port;