Acked-by: Jon Maloy <jon.ma...@ericsson.com>

> -----Original Message-----
> From: Tuong Lien Tong <tuong.t.l...@dektech.com.au>
> Sent: 19-Nov-19 22:37
> To: Jon Maloy <jon.ma...@ericsson.com>; 'Ying Xue' <ying....@windriver.com>; 
> tipc-
> discuss...@lists.sourceforge.net; ma...@donjonn.com
> Subject: RE: [iproute2] tipc: add new commands to set TIPC AEAD key
> 
> Hi Jon/Ying,
> 
> We still have this patch (i.e. for the 'tipc node set/flush key...' 
> commands), may I put your ACK on it before
> sending to iproute2-next?
> Many thanks!
> 
> BR/Tuong
> 
> -----Original Message-----
> From: Jon Maloy <jon.ma...@ericsson.com>
> Sent: Wednesday, October 16, 2019 9:51 PM
> To: Ying Xue <ying....@windriver.com>; Tuong Tong Lien 
> <tuong.t.l...@dektech.com.au>; tipc-
> discuss...@lists.sourceforge.net; ma...@donjonn.com
> Subject: RE: [iproute2] tipc: add new commands to set TIPC AEAD key
> 
> 
> 
> > -----Original Message-----
> > From: Ying Xue <ying....@windriver.com>
> > Sent: 16-Oct-19 08:30
> > To: Tuong Tong Lien <tuong.t.l...@dektech.com.au>; tipc-
> > discuss...@lists.sourceforge.net; Jon Maloy <jon.ma...@ericsson.com>;
> > ma...@donjonn.com
> > Subject: Re: [iproute2] tipc: add new commands to set TIPC AEAD key
> >
> > Tt looks like we will use "tipc node" command to configure static key to 
> > TIPC
> > module, right?
> 
> The key is static in the sense that TIPC itself cannot change the key. But 
> the protocol ensures that keys can
> be replaced without any traffic disturbances.
> 
> >
> > Do we plan to support dynamic key setting? If yes, what kinds of key 
> > exchange
> > protocol would we use? For example, in IPSEC, it uses IKEv2 as its key
> > exchange protocol.
> 
> At the moment we assume there is an external user land framework where node 
> authentication is done
> and where keys are generated and distributed (via TLS) to the nodes.
> When we want to replace a key (probably at fix pre-defined intervals), the 
> framework has to generate new
> keys and distribute/inject those to TIPC.
> 
> >
> > Will key be expired after a specific lifetime? For instance, in
> > IPSEC/Raccoon2 or strongswan, they use rekey feature to provide this
> > function to make security association safer.
> 
> We are considering this, so that the external framework can be kept simpler 
> or even be eliminated. That
> would be the next step, once this series is applied.
> 
> Regards
> ///jon
> 
> 
> >
> > On 10/14/19 7:36 PM, Tuong Lien wrote:
> > > Two new commands are added as part of 'tipc node' command:
> > >
> > >  $tipc node set key KEY [algname ALGNAME] [nodeid NODEID]  $tipc node
> > > flush key
> > >
> > > which enable user to set and remove AEAD keys in kernel TIPC.
> > >
> > > For the 'set key' command, the given 'nodeid' parameter decides the
> > > mode to be applied to the key, particularly:
> > >
> > > - If NODEID is empty, the key is a 'cluster' key which will be used
> > > for all message encryption/decryption from/to the node (i.e. both TX & 
> > > RX).
> > > The same key needs to be set in the other nodes i.e. the 'cluster key'
> > > mode.
> > >
> > > - If NODEID is own node, the key is used for message encryption (TX)
> > > from the node. Whereas, if NODEID is a peer node, the key is for
> > > message decryption (RX) from that peer node.
> > > This is the 'per-node-key' mode that each nodes in the cluster has its
> > > specific (TX) key.
> > >
> > > Signed-off-by: Tuong Lien <tuong.t.l...@dektech.com.au>
> > > ---
> > >  include/uapi/linux/tipc.h         |  21 ++++++
> > >  include/uapi/linux/tipc_netlink.h |   4 ++
> > >  tipc/misc.c                       |  38 +++++++++++
> > >  tipc/misc.h                       |   1 +
> > >  tipc/node.c                       | 133
> > +++++++++++++++++++++++++++++++++++++-
> > >  5 files changed, 195 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
> > > index e16cb4e2..b118ce9b 100644
> > > --- a/include/uapi/linux/tipc.h
> > > +++ b/include/uapi/linux/tipc.h
> > > @@ -232,6 +232,27 @@ struct tipc_sioc_nodeid_req {
> > >   char node_id[TIPC_NODEID_LEN];
> > >  };
> > >
> > > +/*
> > > + * TIPC Crypto, AEAD mode
> > > + */
> > > +#define TIPC_AEAD_MAX_ALG_NAME   (32)
> > > +#define TIPC_AEAD_MIN_KEYLEN     (16 + 4)
> > > +#define TIPC_AEAD_MAX_KEYLEN     (32 + 4)
> > > +
> > > +struct tipc_aead_key {
> > > + char alg_name[TIPC_AEAD_MAX_ALG_NAME];
> > > + unsigned int keylen;    /* in bytes */
> > > + char key[];
> > > +};
> > > +
> > > +#define TIPC_AEAD_KEY_MAX_SIZE   (sizeof(struct tipc_aead_key) + \
> > > +                                         TIPC_AEAD_MAX_KEYLEN)
> > > +
> > > +static inline int tipc_aead_key_size(struct tipc_aead_key *key) {
> > > + return sizeof(*key) + key->keylen;
> > > +}
> > > +
> > >  /* The macros and functions below are deprecated:
> > >   */
> > >
> > > diff --git a/include/uapi/linux/tipc_netlink.h
> > > b/include/uapi/linux/tipc_netlink.h
> > > index efb958fd..6c2194ab 100644
> > > --- a/include/uapi/linux/tipc_netlink.h
> > > +++ b/include/uapi/linux/tipc_netlink.h
> > > @@ -63,6 +63,8 @@ enum {
> > >   TIPC_NL_PEER_REMOVE,
> > >   TIPC_NL_BEARER_ADD,
> > >   TIPC_NL_UDP_GET_REMOTEIP,
> > > + TIPC_NL_KEY_SET,
> > > + TIPC_NL_KEY_FLUSH,
> > >
> > >   __TIPC_NL_CMD_MAX,
> > >   TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -160,6 +162,8
> > @@ enum {
> > >   TIPC_NLA_NODE_UNSPEC,
> > >   TIPC_NLA_NODE_ADDR,             /* u32 */
> > >   TIPC_NLA_NODE_UP,               /* flag */
> > > + TIPC_NLA_NODE_ID,               /* data */
> > > + TIPC_NLA_NODE_KEY,              /* data */
> > >
> > >   __TIPC_NLA_NODE_MAX,
> > >   TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1 diff --git
> > a/tipc/misc.c
> > > b/tipc/misc.c index e4b1cd0c..1daf3072 100644
> > > --- a/tipc/misc.c
> > > +++ b/tipc/misc.c
> > > @@ -98,6 +98,44 @@ int str2nodeid(char *str, uint8_t *id)
> > >   return 0;
> > >  }
> > >
> > > +int str2key(char *str, struct tipc_aead_key *key) {
> > > + int len = strlen(str);
> > > + int ishex = 0;
> > > + int i;
> > > +
> > > + /* Check if the input is a hex string (i.e. 0x...) */
> > > + if (len > 2 && strncmp(str, "0x", 2) == 0) {
> > > +     ishex = is_hex(str + 2, len - 2 - 1);
> > > +     if (ishex) {
> > > +         len -= 2;
> > > +         str += 2;
> > > +     }
> > > + }
> > > +
> > > + /* Obtain key: */
> > > + if (!ishex) {
> > > +         key->keylen = len;
> > > +         memcpy(key->key, str, len);
> > > + } else {
> > > +         /* Convert hex string to key */
> > > +         key->keylen = (len + 1) / 2;
> > > +         for (i = 0; i < key->keylen; i++) {
> > > +                 if (i == 0 && len % 2 != 0) {
> > > +                         if (sscanf(str, "%1hhx", &key->key[0]) != 1)
> > > +                                 return -1;
> > > +                         str += 1;
> > > +                         continue;
> > > +                 }
> > > +                 if (sscanf(str, "%2hhx", &key->key[i]) != 1)
> > > +                         return -1;
> > > +                 str += 2;
> > > +         }
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > >  void nodeid2str(uint8_t *id, char *str)  {
> > >   int i;
> > > diff --git a/tipc/misc.h b/tipc/misc.h index ff2f31f1..59309f68 100644
> > > --- a/tipc/misc.h
> > > +++ b/tipc/misc.h
> > > @@ -18,5 +18,6 @@ uint32_t str2addr(char *str);  int str2nodeid(char
> > > *str, uint8_t *id);  void nodeid2str(uint8_t *id, char *str);  void
> > > hash2nodestr(uint32_t hash, char *str);
> > > +int str2key(char *str, struct tipc_aead_key *key);
> > >
> > >  #endif
> > > diff --git a/tipc/node.c b/tipc/node.c index 2fec6753..fc81bd30 100644
> > > --- a/tipc/node.c
> > > +++ b/tipc/node.c
> > > @@ -157,6 +157,111 @@ static int cmd_node_set_nodeid(struct nlmsghdr
> > *nlh, const struct cmd *cmd,
> > >   return msg_doit(nlh, NULL, NULL);
> > >  }
> > >
> > > +static void cmd_node_set_key_help(struct cmdl *cmdl) {
> > > + fprintf(stderr,
> > > +         "Usage: %s node set key KEY [algname ALGNAME] [nodeid
> > NODEID]\n\n"
> > > +         "PROPERTIES\n"
> > > +         " KEY                   - Symmetric KEY & SALT as a normal or 
> > > hex
> > string\n"
> > > +         "                         that consists of two parts:\n"
> > > +         "                         [KEY: 16, 24 or 32 octets][SALT: 4 
> > > octets]\n\n"
> > > +         " algname ALGNAME       - Default: \"gcm(aes)\"\n\n"
> > > +         " nodeid NODEID         - Own or peer node identity to which the
> > key will\n"
> > > +         "                         be attached. If not present, the key 
> > > is a cluster\n"
> > > +         "                         key!\n\n"
> > > +         "EXAMPLES\n"
> > > +         "  %s node set key this_is_a_key16_salt algname \"gcm(aes)\"
> > nodeid node1\n"
> > > +         "  %s node set key
> > 0x746869735F69735F615F6B657931365F73616C74 nodeid node2\n\n",
> > > +         cmdl->argv[0], cmdl->argv[0], cmdl->argv[0]); }
> > > +
> > > +static int cmd_node_set_key(struct nlmsghdr *nlh, const struct cmd *cmd,
> > > +                     struct cmdl *cmdl, void *data) {
> > > + struct {
> > > +         struct tipc_aead_key key;
> > > +         char mem[TIPC_AEAD_MAX_KEYLEN + 1];
> > > + } input = {};
> > > + struct opt opts[] = {
> > > +         { "algname",    OPT_KEYVAL,     NULL },
> > > +         { "nodeid",     OPT_KEYVAL,     NULL },
> > > +         { NULL }
> > > + };
> > > + struct nlattr *nest;
> > > + struct opt *opt_algname, *opt_nodeid;
> > > + char buf[MNL_SOCKET_BUFFER_SIZE];
> > > + uint8_t id[TIPC_NODEID_LEN] = {0,};
> > > + int keysize;
> > > + char *str;
> > > +
> > > + if (help_flag) {
> > > +         (cmd->help)(cmdl);
> > > +         return -EINVAL;
> > > + }
> > > +
> > > + if (cmdl->optind >= cmdl->argc) {
> > > +         fprintf(stderr, "error, missing key\n");
> > > +         return -EINVAL;
> > > + }
> > > +
> > > + /* Get user key */
> > > + str = shift_cmdl(cmdl);
> > > + if (str2key(str, &input.key)) {
> > > +         fprintf(stderr, "error, invalid key input\n");
> > > +         return -EINVAL;
> > > + }
> > > +
> > > + if (parse_opts(opts, cmdl) < 0)
> > > +         return -EINVAL;
> > > +
> > > + /* Get algorithm name, default: "gcm(aes)" */
> > > + opt_algname = get_opt(opts, "algname");
> > > + if (!opt_algname)
> > > +         strcpy(input.key.alg_name, "gcm(aes)");
> > > + else
> > > +         strcpy(input.key.alg_name, opt_algname->val);
> > > +
> > > + /* Get node identity */
> > > + opt_nodeid = get_opt(opts, "nodeid");
> > > + if (opt_nodeid && str2nodeid(opt_nodeid->val, id)) {
> > > +         fprintf(stderr, "error, invalid node identity\n");
> > > +         return -EINVAL;
> > > + }
> > > +
> > > + /* Init & do the command */
> > > + nlh = msg_init(buf, TIPC_NL_KEY_SET);
> > > + if (!nlh) {
> > > +         fprintf(stderr, "error, message initialisation failed\n");
> > > +         return -1;
> > > + }
> > > + nest = mnl_attr_nest_start(nlh, TIPC_NLA_NODE);
> > > + keysize = tipc_aead_key_size(&input.key);
> > > + mnl_attr_put(nlh, TIPC_NLA_NODE_KEY, keysize, &input.key);
> > > + if (opt_nodeid)
> > > +         mnl_attr_put(nlh, TIPC_NLA_NODE_ID, TIPC_NODEID_LEN, id);
> > > + mnl_attr_nest_end(nlh, nest);
> > > + return msg_doit(nlh, NULL, NULL);
> > > +}
> > > +
> > > +static int cmd_node_flush_key(struct nlmsghdr *nlh, const struct cmd
> > *cmd,
> > > +                       struct cmdl *cmdl, void *data) {
> > > + char buf[MNL_SOCKET_BUFFER_SIZE];
> > > +
> > > + if (help_flag) {
> > > +         (cmd->help)(cmdl);
> > > +         return -EINVAL;
> > > + }
> > > +
> > > + /* Init & do the command */
> > > + nlh = msg_init(buf, TIPC_NL_KEY_FLUSH);
> > > + if (!nlh) {
> > > +         fprintf(stderr, "error, message initialisation failed\n");
> > > +         return -1;
> > > + }
> > > + return msg_doit(nlh, NULL, NULL);
> > > +}
> > > +
> > >  static int nodeid_get_cb(const struct nlmsghdr *nlh, void *data)  {
> > >   struct nlattr *info[TIPC_NLA_MAX + 1] = {}; @@ -270,13 +375,34 @@
> > > static int cmd_node_set_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
> > >   return msg_doit(nlh, NULL, NULL);
> > >  }
> > >
> > > +static void cmd_node_flush_help(struct cmdl *cmdl) {
> > > + fprintf(stderr,
> > > +         "Usage: %s node flush PROPERTY\n\n"
> > > +         "PROPERTIES\n"
> > > +         " key                   - Flush all symmetric-keys\n",
> > > +         cmdl->argv[0]);
> > > +}
> > > +
> > > +static int cmd_node_flush(struct nlmsghdr *nlh, const struct cmd *cmd,
> > > +                   struct cmdl *cmdl, void *data)
> > > +{
> > > + const struct cmd cmds[] = {
> > > +         { "key",        cmd_node_flush_key,     NULL },
> > > +         { NULL }
> > > + };
> > > +
> > > + return run_cmd(nlh, cmd, cmds, cmdl, NULL); }
> > > +
> > >  static void cmd_node_set_help(struct cmdl *cmdl)  {
> > >   fprintf(stderr,
> > >           "Usage: %s node set PROPERTY\n\n"
> > >           "PROPERTIES\n"
> > >           " identity NODEID       - Set node identity\n"
> > > -         " clusterid CLUSTERID   - Set local cluster id\n",
> > > +         " clusterid CLUSTERID   - Set local cluster id\n"
> > > +         " key PROPERTY          - Set symmetric-key\n",
> > >           cmdl->argv[0]);
> > >  }
> > >
> > > @@ -288,6 +414,7 @@ static int cmd_node_set(struct nlmsghdr *nlh,
> > const struct cmd *cmd,
> > >           { "identity",   cmd_node_set_nodeid,    NULL },
> > >           { "netid",      cmd_node_set_netid,     NULL },
> > >           { "clusterid",  cmd_node_set_netid,     NULL },
> > > +         { "key",        cmd_node_set_key,       cmd_node_set_key_help },
> > >           { NULL }
> > >   };
> > >
> > > @@ -325,7 +452,8 @@ void cmd_node_help(struct cmdl *cmdl)
> > >           "COMMANDS\n"
> > >           " list                  - List remote nodes\n"
> > >           " get                   - Get local node parameters\n"
> > > -         " set                   - Set local node parameters\n",
> > > +         " set                   - Set local node parameters\n"
> > > +         " flush                 - Flush local node parameters\n",
> > >           cmdl->argv[0]);
> > >  }
> > >
> > > @@ -336,6 +464,7 @@ int cmd_node(struct nlmsghdr *nlh, const struct
> > cmd *cmd, struct cmdl *cmdl,
> > >           { "list",       cmd_node_list,  NULL },
> > >           { "get",        cmd_node_get,   cmd_node_get_help },
> > >           { "set",        cmd_node_set,   cmd_node_set_help },
> > > +         { "flush",      cmd_node_flush, cmd_node_flush_help},
> > >           { NULL }
> > >   };
> > >
> > >


_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to