Implemented Traffic Flow Confidentiality padding in kernel_interface
authorMartin Willi <martin@revosec.ch>
Tue, 30 Nov 2010 16:17:30 +0000 (16:17 +0000)
committerMartin Willi <martin@revosec.ch>
Mon, 20 Dec 2010 08:45:39 +0000 (09:45 +0100)
src/include/linux/xfrm.h
src/libcharon/plugins/load_tester/load_tester_ipsec.c
src/libcharon/sa/child_sa.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_ipsec.h
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/pluto/kernel.c

index b971e38..930fdd2 100644 (file)
@@ -283,6 +283,7 @@ enum xfrm_attr_type_t {
        XFRMA_KMADDRESS,        /* struct xfrm_user_kmaddress */
        XFRMA_ALG_AUTH_TRUNC,   /* struct xfrm_algo_auth */
        XFRMA_MARK,             /* struct xfrm_mark */
+       XFRMA_TFCPAD,           /* __u32 */
        __XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
index aece95e..ef9d7f9 100644 (file)
@@ -52,7 +52,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
 METHOD(kernel_ipsec_t, add_sa, status_t,
           private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
           u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
-          lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+          u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
           u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
           u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
           traffic_selector_t *dst_ts)
index 74ad97c..47518d6 100644 (file)
@@ -566,6 +566,7 @@ METHOD(child_sa_t, install, status_t,
        traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
        time_t now;
        lifetime_cfg_t *lifetime;
+       u_int32_t tfc = 0;
        host_t *src, *dst;
        status_t status;
        bool update = FALSE;
@@ -639,7 +640,7 @@ METHOD(child_sa_t, install, status_t,
 
        status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
                                src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
-                               inbound ? this->mark_in : this->mark_out,
+                               inbound ? this->mark_in : this->mark_out, tfc,
                                lifetime, enc_alg, encr, int_alg, integ, this->mode,
                                this->ipcomp, cpi, this->encap, update, src_ts, dst_ts);
 
index 3e6d462..4fd5a75 100644 (file)
@@ -78,8 +78,8 @@ METHOD(kernel_interface_t, get_cpi, status_t,
 
 METHOD(kernel_interface_t, add_sa, status_t,
        private_kernel_interface_t *this, host_t *src, host_t *dst,
-       u_int32_t spi, u_int8_t protocol, u_int32_t reqid,
-       mark_t mark, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+       u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
+       u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key,     ipsec_mode_t mode, u_int16_t ipcomp,
        u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
        traffic_selector_t *dst_ts)
@@ -89,8 +89,8 @@ METHOD(kernel_interface_t, add_sa, status_t,
                return NOT_SUPPORTED;
        }
        return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
-                       mark, lifetime, enc_alg, enc_key, int_alg, int_key,     mode, ipcomp,
-                       cpi, encap, inbound, src_ts, dst_ts);
+                       mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
+                       ipcomp, cpi, encap, inbound, src_ts, dst_ts);
 }
 
 METHOD(kernel_interface_t, update_sa, status_t,
index 8b0c7a2..ec73fa1 100644 (file)
@@ -91,6 +91,7 @@ struct kernel_interface_t {
         * @param protocol              protocol for this SA (ESP/AH)
         * @param reqid                 unique ID for this SA
         * @param mark                  optional mark for this SA
+        * @param tfc                   Traffic Flow Confidentiality padding for this SA
         * @param lifetime              lifetime_cfg_t for this SA
         * @param enc_alg               Algorithm to use for encryption (ESP only)
         * @param enc_key               key to use for encryption
@@ -108,7 +109,7 @@ struct kernel_interface_t {
        status_t (*add_sa) (kernel_interface_t *this,
                                                host_t *src, host_t *dst, u_int32_t spi,
                                                u_int8_t protocol, u_int32_t reqid, mark_t mark,
-                                               lifetime_cfg_t *lifetime,
+                                               u_int32_t tfc, lifetime_cfg_t *lifetime,
                                                u_int16_t enc_alg, chunk_t enc_key,
                                                u_int16_t int_alg, chunk_t int_key,
                                                ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
index 49d9cc0..3e2d8b9 100644 (file)
@@ -204,6 +204,7 @@ struct kernel_ipsec_t {
         * @param protocol              protocol for this SA (ESP/AH)
         * @param reqid                 unique ID for this SA
         * @param mark                  mark for this SA
+        * @param tfc                   Traffic Flow Confidentiality padding for this SA
         * @param lifetime              lifetime_cfg_t for this SA
         * @param enc_alg               Algorithm to use for encryption (ESP only)
         * @param enc_key               key to use for encryption
@@ -221,7 +222,7 @@ struct kernel_ipsec_t {
        status_t (*add_sa) (kernel_ipsec_t *this,
                                                host_t *src, host_t *dst, u_int32_t spi,
                                                u_int8_t protocol, u_int32_t reqid,
-                                               mark_t mark, lifetime_cfg_t *lifetime,
+                                               mark_t mark, u_int32_t tfc, lifetime_cfg_t *lifetime,
                                                u_int16_t enc_alg, chunk_t enc_key,
                                                u_int16_t int_alg, chunk_t int_key,
                                                ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
index d2b9392..4dc8078 100644 (file)
@@ -866,7 +866,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
 METHOD(kernel_ipsec_t, add_sa, status_t,
        private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
        u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
-       lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+       u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
        u_int16_t cpi, bool encap, bool inbound,
        traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
@@ -882,7 +882,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        if (ipcomp != IPCOMP_NONE && cpi != 0)
        {
                lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
-               add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
+               add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, tfc,
                           &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
                           mode, ipcomp, 0, FALSE, inbound, NULL, NULL);
                ipcomp = IPCOMP_NONE;
@@ -1154,6 +1154,24 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
                rthdr = XFRM_RTA_NEXT(rthdr);
        }
 
+       if (tfc)
+       {
+               u_int32_t *tfcpad;
+
+               rthdr->rta_type = XFRMA_TFCPAD;
+               rthdr->rta_len = RTA_LENGTH(sizeof(u_int32_t));
+
+               hdr->nlmsg_len += rthdr->rta_len;
+               if (hdr->nlmsg_len > sizeof(request))
+               {
+                       return FAILED;
+               }
+
+               tfcpad = (u_int32_t*)RTA_DATA(rthdr);
+               *tfcpad = tfc;
+               rthdr = XFRM_RTA_NEXT(rthdr);
+       }
+
        if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
        {
                if (mark.value)
index e57822f..104b6c2 100644 (file)
@@ -1183,7 +1183,7 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
 
                if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
                                                host_dst, ipcomp_spi, said_next->proto, c->spd.reqid,
-                                               mark, &lt_none, ENCR_UNDEFINED, chunk_empty,
+                                               mark, 0, &lt_none, ENCR_UNDEFINED, chunk_empty,
                                                AUTH_UNDEFINED, chunk_empty, mode,
                                                st->st_ipcomp.attrs.transid, 0 /* cpi */, FALSE,
                                                inbound, NULL, NULL) != SUCCESS)
@@ -1292,7 +1292,7 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
 
                if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
                                                host_dst, esp_spi, said_next->proto, c->spd.reqid,
-                                               mark, &lt_none, enc_alg, enc_key,
+                                               mark, 0, &lt_none, enc_alg, enc_key,
                                                auth_alg, auth_key, mode, IPCOMP_NONE, 0 /* cpi */,
                                                encap, inbound, NULL, NULL) != SUCCESS)
                {
@@ -1325,7 +1325,7 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
 
                if (hydra->kernel_interface->add_sa(hydra->kernel_interface, host_src,
                                                host_dst, ah_spi, said_next->proto, c->spd.reqid,
-                                               mark, &lt_none, ENCR_UNDEFINED, chunk_empty,
+                                               mark, 0, &lt_none, ENCR_UNDEFINED, chunk_empty,
                                                auth_alg, auth_key, mode, IPCOMP_NONE, 0 /* cpi */,
                                                FALSE, inbound, NULL, NULL) != SUCCESS)
                {