Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #ifndef _XFRM_CONTROLLER_H
     17 #define _XFRM_CONTROLLER_H
     18 
     19 #include <atomic>
     20 #include <list>
     21 #include <map>
     22 #include <string>
     23 #include <utility> // for pair
     24 
     25 #include <linux/if_link.h>
     26 #include <linux/if_tunnel.h>
     27 #include <linux/netlink.h>
     28 #include <linux/udp.h>
     29 #include <linux/xfrm.h>
     30 #include <sysutils/SocketClient.h>
     31 
     32 #include "NetdConstants.h"
     33 #include "netdutils/Slice.h"
     34 #include "netdutils/Status.h"
     35 
     36 namespace android {
     37 namespace net {
     38 
     39 // Exposed for testing
     40 extern const uint32_t ALGO_MASK_AUTH_ALL;
     41 // Exposed for testing
     42 extern const uint32_t ALGO_MASK_CRYPT_ALL;
     43 // Exposed for testing
     44 extern const uint32_t ALGO_MASK_AEAD_ALL;
     45 // Exposed for testing
     46 extern const uint8_t REPLAY_WINDOW_SIZE;
     47 
     48 // Suggest we avoid the smallest and largest ints
     49 class XfrmMessage;
     50 class TransportModeSecurityAssociation;
     51 
     52 class XfrmSocket {
     53 public:
     54     virtual void close() {
     55         if (mSock >= 0) {
     56             ::close(mSock);
     57         }
     58         mSock = -1;
     59     }
     60 
     61     virtual netdutils::Status open() = 0;
     62 
     63     virtual ~XfrmSocket() { close(); }
     64 
     65     // Sends the netlink message contained in iovecs. This populates iovecs[0] with
     66     // a valid netlink message header.
     67     virtual netdutils::Status sendMessage(uint16_t nlMsgType, uint16_t nlMsgFlags,
     68                                           uint16_t nlMsgSeqNum,
     69                                           std::vector<iovec>* iovecs) const = 0;
     70 
     71 protected:
     72     int mSock;
     73 };
     74 
     75 enum struct XfrmDirection : uint8_t {
     76     IN = XFRM_POLICY_IN,
     77     OUT = XFRM_POLICY_OUT,
     78     FORWARD = XFRM_POLICY_FWD,
     79     MASK = XFRM_POLICY_MASK,
     80 };
     81 
     82 enum struct XfrmMode : uint8_t {
     83     TRANSPORT = XFRM_MODE_TRANSPORT,
     84     TUNNEL = XFRM_MODE_TUNNEL,
     85 };
     86 
     87 enum struct XfrmEncapType : uint16_t {
     88     NONE = 0,
     89     ESPINUDP_NON_IKE = UDP_ENCAP_ESPINUDP_NON_IKE,
     90     ESPINUDP = UDP_ENCAP_ESPINUDP
     91 };
     92 
     93 struct XfrmAlgo {
     94     std::string name;
     95     std::vector<uint8_t> key;
     96     uint16_t truncLenBits;
     97 };
     98 
     99 struct XfrmEncap {
    100     XfrmEncapType type;
    101     uint16_t srcPort;
    102     uint16_t dstPort;
    103 };
    104 
    105 // minimally sufficient structure to match either an SA or a Policy
    106 struct XfrmId {
    107     xfrm_address_t dstAddr; // network order
    108     xfrm_address_t srcAddr;
    109     int addrFamily;  // AF_INET or AF_INET6
    110     int transformId; // requestId
    111     int spi;
    112     xfrm_mark mark;
    113 };
    114 
    115 struct XfrmSaInfo : XfrmId {
    116     XfrmAlgo auth;
    117     XfrmAlgo crypt;
    118     XfrmAlgo aead;
    119     int netId;
    120     XfrmMode mode;
    121     XfrmEncap encap;
    122 };
    123 
    124 class XfrmController {
    125 public:
    126     XfrmController();
    127 
    128     static netdutils::Status Init();
    129 
    130     static netdutils::Status ipSecSetEncapSocketOwner(const android::base::unique_fd& socket,
    131                                                       int newUid, uid_t callerUid);
    132 
    133     static netdutils::Status ipSecAllocateSpi(int32_t transformId, const std::string& localAddress,
    134                                               const std::string& remoteAddress, int32_t inSpi,
    135                                               int32_t* outSpi);
    136 
    137     static netdutils::Status ipSecAddSecurityAssociation(
    138         int32_t transformId, int32_t mode, const std::string& sourceAddress,
    139         const std::string& destinationAddress, int32_t underlyingNetId, int32_t spi,
    140         int32_t markValue, int32_t markMask, const std::string& authAlgo,
    141         const std::vector<uint8_t>& authKey, int32_t authTruncBits, const std::string& cryptAlgo,
    142         const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits, const std::string& aeadAlgo,
    143         const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits, int32_t encapType,
    144         int32_t encapLocalPort, int32_t encapRemotePort);
    145 
    146     static netdutils::Status ipSecDeleteSecurityAssociation(int32_t transformId,
    147                                                             const std::string& sourceAddress,
    148                                                             const std::string& destinationAddress,
    149                                                             int32_t spi, int32_t markValue,
    150                                                             int32_t markMask);
    151 
    152     static netdutils::Status
    153     ipSecApplyTransportModeTransform(const android::base::unique_fd& socket, int32_t transformId,
    154                                      int32_t direction, const std::string& localAddress,
    155                                      const std::string& remoteAddress, int32_t spi);
    156 
    157     static netdutils::Status
    158     ipSecRemoveTransportModeTransform(const android::base::unique_fd& socket);
    159 
    160     static netdutils::Status ipSecAddSecurityPolicy(int32_t transformId, int32_t direction,
    161                                                     const std::string& sourceAddress,
    162                                                     const std::string& destinationAddress,
    163                                                     int32_t spi, int32_t markValue,
    164                                                     int32_t markMask);
    165 
    166     static netdutils::Status ipSecUpdateSecurityPolicy(int32_t transformId, int32_t direction,
    167                                                        const std::string& sourceAddress,
    168                                                        const std::string& destinationAddress,
    169                                                        int32_t spi, int32_t markValue,
    170                                                        int32_t markMask);
    171 
    172     static netdutils::Status ipSecDeleteSecurityPolicy(int32_t transformId, int32_t direction,
    173                                                        const std::string& sourceAddress,
    174                                                        const std::string& destinationAddress,
    175                                                        int32_t markValue, int32_t markMask);
    176 
    177     static int addVirtualTunnelInterface(const std::string& deviceName,
    178                                          const std::string& localAddress,
    179                                          const std::string& remoteAddress, int32_t ikey,
    180                                          int32_t okey, bool isUpdate);
    181 
    182     static int removeVirtualTunnelInterface(const std::string& deviceName);
    183 
    184     // Some XFRM netlink attributes comprise a header, a struct, and some data
    185     // after the struct. We wrap all of those in one struct for easier
    186     // marshalling. The structs below must be ABI compatible with the kernel and
    187     // are composed from kernel structures; thus, they use the kernel naming
    188     // convention.
    189 
    190     // Exposed for testing
    191     static constexpr size_t MAX_KEY_LENGTH = 128;
    192 
    193     // Container for the content of an XFRMA_ALG_CRYPT netlink attribute.
    194     // Exposed for testing
    195     struct nlattr_algo_crypt {
    196         nlattr hdr;
    197         xfrm_algo crypt;
    198         uint8_t key[MAX_KEY_LENGTH];
    199     };
    200 
    201     // Container for the content of an XFRMA_ALG_AUTH_TRUNC netlink attribute.
    202     // Exposed for testing
    203     struct nlattr_algo_auth {
    204         nlattr hdr;
    205         xfrm_algo_auth auth;
    206         uint8_t key[MAX_KEY_LENGTH];
    207     };
    208 
    209     // Container for the content of an XFRMA_TMPL netlink attribute.
    210     // Exposed for testing
    211     struct nlattr_algo_aead {
    212         nlattr hdr;
    213         xfrm_algo_aead aead;
    214         uint8_t key[MAX_KEY_LENGTH];
    215     };
    216 
    217     // Exposed for testing
    218     struct nlattr_user_tmpl {
    219         nlattr hdr;
    220         xfrm_user_tmpl tmpl;
    221     };
    222 
    223     // Container for the content of an XFRMA_ENCAP netlink attribute.
    224     // Exposed for testing
    225     struct nlattr_encap_tmpl {
    226         nlattr hdr;
    227         xfrm_encap_tmpl tmpl;
    228     };
    229 
    230     // Container for the content of an XFRMA_MARK netlink attribute.
    231     // Exposed for testing
    232     struct nlattr_xfrm_mark {
    233         nlattr hdr;
    234         xfrm_mark mark;
    235     };
    236 
    237     // Container for the content of an XFRMA_OUTPUT_MARK netlink attribute.
    238     // Exposed for testing
    239     struct nlattr_xfrm_output_mark {
    240         nlattr hdr;
    241         __u32 outputMark;
    242     };
    243 
    244 private:
    245 /*
    246  * Below is a redefinition of the xfrm_usersa_info struct that is part
    247  * of the Linux uapi <linux/xfrm.h> to align the structures to a 64-bit
    248  * boundary.
    249  */
    250 #ifdef NETLINK_COMPAT32
    251     // Shadow the kernel definition of xfrm_usersa_info with a 64-bit aligned version
    252     struct xfrm_usersa_info : ::xfrm_usersa_info {
    253     } __attribute__((aligned(8)));
    254     // Shadow the kernel's version, using the aligned version of xfrm_usersa_info
    255     struct xfrm_userspi_info {
    256         struct xfrm_usersa_info info;
    257         __u32 min;
    258         __u32 max;
    259     };
    260 
    261     /*
    262      * Anyone who encounters a failure when sending netlink messages should look here
    263      * first. Hitting the static_assert() below should be a strong hint that Android
    264      * IPsec will probably not work with your current settings.
    265      *
    266      * Again, experimentally determined, the "flags" field should be the first byte in
    267      * the final word of the xfrm_usersa_info struct. The check validates the size of
    268      * the padding to be 7.
    269      *
    270      * This padding is verified to be correct on gcc/x86_64 kernel, and clang/x86 userspace.
    271      */
    272     static_assert(sizeof(::xfrm_usersa_info) % 8 != 0, "struct xfrm_usersa_info has changed "
    273                                                        "alignment. Please consider whether this "
    274                                                        "patch is needed.");
    275     static_assert(sizeof(xfrm_usersa_info) - offsetof(xfrm_usersa_info, flags) == 8,
    276                   "struct xfrm_usersa_info probably misaligned with kernel struct.");
    277     static_assert(sizeof(xfrm_usersa_info) % 8 == 0, "struct xfrm_usersa_info_t is not 64-bit  "
    278                                                      "aligned. Please consider whether this patch "
    279                                                      "is needed.");
    280     static_assert(sizeof(::xfrm_userspi_info) - sizeof(::xfrm_usersa_info) ==
    281                       sizeof(xfrm_userspi_info) - sizeof(xfrm_usersa_info),
    282                   "struct xfrm_userspi_info has changed and does not match the kernel struct.");
    283 #endif
    284 
    285     // helper function for filling in the XfrmId (and XfrmSaInfo) structure
    286     static netdutils::Status fillXfrmId(const std::string& sourceAddress,
    287                                         const std::string& destinationAddress, int32_t spi,
    288                                         int32_t markValue, int32_t markMask, int32_t transformId,
    289                                         XfrmId* xfrmId);
    290 
    291     // Top level functions for managing a Transport Mode Transform
    292     static netdutils::Status addTransportModeTransform(const XfrmSaInfo& record);
    293     static int removeTransportModeTransform(const XfrmSaInfo& record);
    294 
    295     // TODO(messagerefactor): FACTOR OUT ALL MESSAGE BUILDING CODE BELOW HERE
    296     // Shared between SA and SP
    297     static void fillXfrmSelector(const XfrmSaInfo& record, xfrm_selector* selector);
    298 
    299     // Shared between Transport and Tunnel Mode
    300     static int fillNlAttrXfrmAlgoEnc(const XfrmAlgo& in_algo, nlattr_algo_crypt* algo);
    301     static int fillNlAttrXfrmAlgoAuth(const XfrmAlgo& in_algo, nlattr_algo_auth* algo);
    302     static int fillNlAttrXfrmAlgoAead(const XfrmAlgo& in_algo, nlattr_algo_aead* algo);
    303     static int fillNlAttrXfrmEncapTmpl(const XfrmSaInfo& record, nlattr_encap_tmpl* tmpl);
    304 
    305     // Functions for updating a Transport Mode SA
    306     static netdutils::Status updateSecurityAssociation(const XfrmSaInfo& record,
    307                                                        const XfrmSocket& sock);
    308     static int fillUserSaInfo(const XfrmSaInfo& record, xfrm_usersa_info* usersa);
    309 
    310     // Functions for deleting a Transport Mode SA
    311     static netdutils::Status deleteSecurityAssociation(const XfrmId& record,
    312                                                        const XfrmSocket& sock);
    313     static int fillUserSaId(const XfrmId& record, xfrm_usersa_id* said);
    314     static int fillUserTemplate(const XfrmSaInfo& record, xfrm_user_tmpl* tmpl);
    315 
    316     static int fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction,
    317                                            xfrm_userpolicy_info* usersp);
    318     static int fillNlAttrUserTemplate(const XfrmSaInfo& record, nlattr_user_tmpl* tmpl);
    319     static int fillUserPolicyId(const XfrmSaInfo& record, XfrmDirection direction,
    320                                 xfrm_userpolicy_id* policy_id);
    321     static int fillNlAttrXfrmMark(const XfrmId& record, nlattr_xfrm_mark* mark);
    322     static int fillNlAttrXfrmOutputMark(const __u32 output_mark_value,
    323                                         nlattr_xfrm_output_mark* output_mark);
    324 
    325     static netdutils::Status allocateSpi(const XfrmSaInfo& record, uint32_t minSpi, uint32_t maxSpi,
    326                                          uint32_t* outSpi, const XfrmSocket& sock);
    327 
    328     static netdutils::Status processSecurityPolicy(int32_t transformId, int32_t direction,
    329                                                    const std::string& localAddress,
    330                                                    const std::string& remoteAddress, int32_t spi,
    331                                                    int32_t markValue, int32_t markMask,
    332                                                    int32_t msgType);
    333     static netdutils::Status updateTunnelModeSecurityPolicy(const XfrmSaInfo& record,
    334                                                             const XfrmSocket& sock,
    335                                                             XfrmDirection direction,
    336                                                             uint16_t msgType);
    337     static netdutils::Status deleteTunnelModeSecurityPolicy(const XfrmSaInfo& record,
    338                                                             const XfrmSocket& sock,
    339                                                             XfrmDirection direction);
    340     static netdutils::Status flushInterfaces();
    341     static netdutils::Status flushSaDb(const XfrmSocket& s);
    342     static netdutils::Status flushPolicyDb(const XfrmSocket& s);
    343 
    344     // END TODO(messagerefactor)
    345 };
    346 
    347 } // namespace net
    348 } // namespace android
    349 
    350 #endif /* !defined(XFRM_CONTROLLER_H) */
    351