1a61127c2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2cac5818cSCorentin Labbe /* 3cac5818cSCorentin Labbe * Crypto user configuration API. 4cac5818cSCorentin Labbe * 5cac5818cSCorentin Labbe * Copyright (C) 2011 secunet Security Networks AG 6cac5818cSCorentin Labbe * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com> 7cac5818cSCorentin Labbe */ 8cac5818cSCorentin Labbe 9cac5818cSCorentin Labbe #include <linux/module.h> 10cac5818cSCorentin Labbe #include <linux/crypto.h> 11cac5818cSCorentin Labbe #include <linux/cryptouser.h> 12cac5818cSCorentin Labbe #include <linux/sched.h> 13cac5818cSCorentin Labbe #include <net/netlink.h> 14cac5818cSCorentin Labbe #include <linux/security.h> 15cac5818cSCorentin Labbe #include <net/net_namespace.h> 16cac5818cSCorentin Labbe #include <crypto/internal/skcipher.h> 17cac5818cSCorentin Labbe #include <crypto/internal/rng.h> 18cac5818cSCorentin Labbe #include <crypto/akcipher.h> 19cac5818cSCorentin Labbe #include <crypto/kpp.h> 20cac5818cSCorentin Labbe #include <crypto/internal/cryptouser.h> 21cac5818cSCorentin Labbe 22cac5818cSCorentin Labbe #include "internal.h" 23cac5818cSCorentin Labbe 24cac5818cSCorentin Labbe #define null_terminated(x) (strnlen(x, sizeof(x)) < sizeof(x)) 25cac5818cSCorentin Labbe 26cac5818cSCorentin Labbe static DEFINE_MUTEX(crypto_cfg_mutex); 27cac5818cSCorentin Labbe 28cac5818cSCorentin Labbe /* The crypto netlink socket */ 29cac5818cSCorentin Labbe struct sock *crypto_nlsk; 30cac5818cSCorentin Labbe 31cac5818cSCorentin Labbe struct crypto_dump_info { 32cac5818cSCorentin Labbe struct sk_buff *in_skb; 33cac5818cSCorentin Labbe struct sk_buff *out_skb; 34cac5818cSCorentin Labbe u32 nlmsg_seq; 35cac5818cSCorentin Labbe u16 nlmsg_flags; 36cac5818cSCorentin Labbe }; 37cac5818cSCorentin Labbe 38cac5818cSCorentin Labbe struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) 39cac5818cSCorentin Labbe { 40cac5818cSCorentin Labbe struct crypto_alg *q, *alg = NULL; 41cac5818cSCorentin Labbe 42cac5818cSCorentin Labbe down_read(&crypto_alg_sem); 43cac5818cSCorentin Labbe 44cac5818cSCorentin Labbe list_for_each_entry(q, &crypto_alg_list, cra_list) { 45cac5818cSCorentin Labbe int match = 0; 46cac5818cSCorentin Labbe 47cac5818cSCorentin Labbe if ((q->cra_flags ^ p->cru_type) & p->cru_mask) 48cac5818cSCorentin Labbe continue; 49cac5818cSCorentin Labbe 50cac5818cSCorentin Labbe if (strlen(p->cru_driver_name)) 51cac5818cSCorentin Labbe match = !strcmp(q->cra_driver_name, 52cac5818cSCorentin Labbe p->cru_driver_name); 53cac5818cSCorentin Labbe else if (!exact) 54cac5818cSCorentin Labbe match = !strcmp(q->cra_name, p->cru_name); 55cac5818cSCorentin Labbe 56cac5818cSCorentin Labbe if (!match) 57cac5818cSCorentin Labbe continue; 58cac5818cSCorentin Labbe 59cac5818cSCorentin Labbe if (unlikely(!crypto_mod_get(q))) 60cac5818cSCorentin Labbe continue; 61cac5818cSCorentin Labbe 62cac5818cSCorentin Labbe alg = q; 63cac5818cSCorentin Labbe break; 64cac5818cSCorentin Labbe } 65cac5818cSCorentin Labbe 66cac5818cSCorentin Labbe up_read(&crypto_alg_sem); 67cac5818cSCorentin Labbe 68cac5818cSCorentin Labbe return alg; 69cac5818cSCorentin Labbe } 70cac5818cSCorentin Labbe 71cac5818cSCorentin Labbe static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) 72cac5818cSCorentin Labbe { 73cac5818cSCorentin Labbe struct crypto_report_cipher rcipher; 74cac5818cSCorentin Labbe 7537db69e0SEric Biggers memset(&rcipher, 0, sizeof(rcipher)); 7637db69e0SEric Biggers 7737db69e0SEric Biggers strscpy(rcipher.type, "cipher", sizeof(rcipher.type)); 78cac5818cSCorentin Labbe 79cac5818cSCorentin Labbe rcipher.blocksize = alg->cra_blocksize; 80cac5818cSCorentin Labbe rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; 81cac5818cSCorentin Labbe rcipher.max_keysize = alg->cra_cipher.cia_max_keysize; 82cac5818cSCorentin Labbe 8337db69e0SEric Biggers return nla_put(skb, CRYPTOCFGA_REPORT_CIPHER, 8437db69e0SEric Biggers sizeof(rcipher), &rcipher); 85cac5818cSCorentin Labbe } 86cac5818cSCorentin Labbe 87cac5818cSCorentin Labbe static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) 88cac5818cSCorentin Labbe { 89cac5818cSCorentin Labbe struct crypto_report_comp rcomp; 90cac5818cSCorentin Labbe 9137db69e0SEric Biggers memset(&rcomp, 0, sizeof(rcomp)); 92cac5818cSCorentin Labbe 9337db69e0SEric Biggers strscpy(rcomp.type, "compression", sizeof(rcomp.type)); 9437db69e0SEric Biggers 9537db69e0SEric Biggers return nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, sizeof(rcomp), &rcomp); 96cac5818cSCorentin Labbe } 97cac5818cSCorentin Labbe 98cac5818cSCorentin Labbe static int crypto_report_one(struct crypto_alg *alg, 99cac5818cSCorentin Labbe struct crypto_user_alg *ualg, struct sk_buff *skb) 100cac5818cSCorentin Labbe { 10137db69e0SEric Biggers memset(ualg, 0, sizeof(*ualg)); 10237db69e0SEric Biggers 10337db69e0SEric Biggers strscpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); 10437db69e0SEric Biggers strscpy(ualg->cru_driver_name, alg->cra_driver_name, 105cac5818cSCorentin Labbe sizeof(ualg->cru_driver_name)); 10637db69e0SEric Biggers strscpy(ualg->cru_module_name, module_name(alg->cra_module), 107cac5818cSCorentin Labbe sizeof(ualg->cru_module_name)); 108cac5818cSCorentin Labbe 109cac5818cSCorentin Labbe ualg->cru_type = 0; 110cac5818cSCorentin Labbe ualg->cru_mask = 0; 111cac5818cSCorentin Labbe ualg->cru_flags = alg->cra_flags; 112cac5818cSCorentin Labbe ualg->cru_refcnt = refcount_read(&alg->cra_refcnt); 113cac5818cSCorentin Labbe 114cac5818cSCorentin Labbe if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority)) 115cac5818cSCorentin Labbe goto nla_put_failure; 116cac5818cSCorentin Labbe if (alg->cra_flags & CRYPTO_ALG_LARVAL) { 117cac5818cSCorentin Labbe struct crypto_report_larval rl; 118cac5818cSCorentin Labbe 11937db69e0SEric Biggers memset(&rl, 0, sizeof(rl)); 12037db69e0SEric Biggers strscpy(rl.type, "larval", sizeof(rl.type)); 12137db69e0SEric Biggers if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL, sizeof(rl), &rl)) 122cac5818cSCorentin Labbe goto nla_put_failure; 123cac5818cSCorentin Labbe goto out; 124cac5818cSCorentin Labbe } 125cac5818cSCorentin Labbe 126cac5818cSCorentin Labbe if (alg->cra_type && alg->cra_type->report) { 127cac5818cSCorentin Labbe if (alg->cra_type->report(skb, alg)) 128cac5818cSCorentin Labbe goto nla_put_failure; 129cac5818cSCorentin Labbe 130cac5818cSCorentin Labbe goto out; 131cac5818cSCorentin Labbe } 132cac5818cSCorentin Labbe 133cac5818cSCorentin Labbe switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { 134cac5818cSCorentin Labbe case CRYPTO_ALG_TYPE_CIPHER: 135cac5818cSCorentin Labbe if (crypto_report_cipher(skb, alg)) 136cac5818cSCorentin Labbe goto nla_put_failure; 137cac5818cSCorentin Labbe 138cac5818cSCorentin Labbe break; 139cac5818cSCorentin Labbe case CRYPTO_ALG_TYPE_COMPRESS: 140cac5818cSCorentin Labbe if (crypto_report_comp(skb, alg)) 141cac5818cSCorentin Labbe goto nla_put_failure; 142cac5818cSCorentin Labbe 143cac5818cSCorentin Labbe break; 144cac5818cSCorentin Labbe } 145cac5818cSCorentin Labbe 146cac5818cSCorentin Labbe out: 147cac5818cSCorentin Labbe return 0; 148cac5818cSCorentin Labbe 149cac5818cSCorentin Labbe nla_put_failure: 150cac5818cSCorentin Labbe return -EMSGSIZE; 151cac5818cSCorentin Labbe } 152cac5818cSCorentin Labbe 153cac5818cSCorentin Labbe static int crypto_report_alg(struct crypto_alg *alg, 154cac5818cSCorentin Labbe struct crypto_dump_info *info) 155cac5818cSCorentin Labbe { 156cac5818cSCorentin Labbe struct sk_buff *in_skb = info->in_skb; 157cac5818cSCorentin Labbe struct sk_buff *skb = info->out_skb; 158cac5818cSCorentin Labbe struct nlmsghdr *nlh; 159cac5818cSCorentin Labbe struct crypto_user_alg *ualg; 160cac5818cSCorentin Labbe int err = 0; 161cac5818cSCorentin Labbe 162cac5818cSCorentin Labbe nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq, 163cac5818cSCorentin Labbe CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags); 164cac5818cSCorentin Labbe if (!nlh) { 165cac5818cSCorentin Labbe err = -EMSGSIZE; 166cac5818cSCorentin Labbe goto out; 167cac5818cSCorentin Labbe } 168cac5818cSCorentin Labbe 169cac5818cSCorentin Labbe ualg = nlmsg_data(nlh); 170cac5818cSCorentin Labbe 171cac5818cSCorentin Labbe err = crypto_report_one(alg, ualg, skb); 172cac5818cSCorentin Labbe if (err) { 173cac5818cSCorentin Labbe nlmsg_cancel(skb, nlh); 174cac5818cSCorentin Labbe goto out; 175cac5818cSCorentin Labbe } 176cac5818cSCorentin Labbe 177cac5818cSCorentin Labbe nlmsg_end(skb, nlh); 178cac5818cSCorentin Labbe 179cac5818cSCorentin Labbe out: 180cac5818cSCorentin Labbe return err; 181cac5818cSCorentin Labbe } 182cac5818cSCorentin Labbe 183cac5818cSCorentin Labbe static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, 184cac5818cSCorentin Labbe struct nlattr **attrs) 185cac5818cSCorentin Labbe { 186cac5818cSCorentin Labbe struct crypto_user_alg *p = nlmsg_data(in_nlh); 187cac5818cSCorentin Labbe struct crypto_alg *alg; 188cac5818cSCorentin Labbe struct sk_buff *skb; 189cac5818cSCorentin Labbe struct crypto_dump_info info; 190cac5818cSCorentin Labbe int err; 191cac5818cSCorentin Labbe 192cac5818cSCorentin Labbe if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 193cac5818cSCorentin Labbe return -EINVAL; 194cac5818cSCorentin Labbe 195cac5818cSCorentin Labbe alg = crypto_alg_match(p, 0); 196cac5818cSCorentin Labbe if (!alg) 197cac5818cSCorentin Labbe return -ENOENT; 198cac5818cSCorentin Labbe 199cac5818cSCorentin Labbe err = -ENOMEM; 200cac5818cSCorentin Labbe skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 201cac5818cSCorentin Labbe if (!skb) 202cac5818cSCorentin Labbe goto drop_alg; 203cac5818cSCorentin Labbe 204cac5818cSCorentin Labbe info.in_skb = in_skb; 205cac5818cSCorentin Labbe info.out_skb = skb; 206cac5818cSCorentin Labbe info.nlmsg_seq = in_nlh->nlmsg_seq; 207cac5818cSCorentin Labbe info.nlmsg_flags = 0; 208cac5818cSCorentin Labbe 209cac5818cSCorentin Labbe err = crypto_report_alg(alg, &info); 210cac5818cSCorentin Labbe 211cac5818cSCorentin Labbe drop_alg: 212cac5818cSCorentin Labbe crypto_mod_put(alg); 213cac5818cSCorentin Labbe 214cac5818cSCorentin Labbe if (err) 215cac5818cSCorentin Labbe return err; 216cac5818cSCorentin Labbe 217cac5818cSCorentin Labbe return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid); 218cac5818cSCorentin Labbe } 219cac5818cSCorentin Labbe 220cac5818cSCorentin Labbe static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) 221cac5818cSCorentin Labbe { 2220ac6b8fbSEric Biggers const size_t start_pos = cb->args[0]; 2230ac6b8fbSEric Biggers size_t pos = 0; 224cac5818cSCorentin Labbe struct crypto_dump_info info; 2250ac6b8fbSEric Biggers struct crypto_alg *alg; 2260ac6b8fbSEric Biggers int res; 227cac5818cSCorentin Labbe 228cac5818cSCorentin Labbe info.in_skb = cb->skb; 229cac5818cSCorentin Labbe info.out_skb = skb; 230cac5818cSCorentin Labbe info.nlmsg_seq = cb->nlh->nlmsg_seq; 231cac5818cSCorentin Labbe info.nlmsg_flags = NLM_F_MULTI; 232cac5818cSCorentin Labbe 2330ac6b8fbSEric Biggers down_read(&crypto_alg_sem); 234cac5818cSCorentin Labbe list_for_each_entry(alg, &crypto_alg_list, cra_list) { 2350ac6b8fbSEric Biggers if (pos >= start_pos) { 2360ac6b8fbSEric Biggers res = crypto_report_alg(alg, &info); 2370ac6b8fbSEric Biggers if (res == -EMSGSIZE) 2380ac6b8fbSEric Biggers break; 2390ac6b8fbSEric Biggers if (res) 2400ac6b8fbSEric Biggers goto out; 241cac5818cSCorentin Labbe } 2420ac6b8fbSEric Biggers pos++; 2430ac6b8fbSEric Biggers } 2440ac6b8fbSEric Biggers cb->args[0] = pos; 2450ac6b8fbSEric Biggers res = skb->len; 246cac5818cSCorentin Labbe out: 2470ac6b8fbSEric Biggers up_read(&crypto_alg_sem); 2480ac6b8fbSEric Biggers return res; 249cac5818cSCorentin Labbe } 250cac5818cSCorentin Labbe 251cac5818cSCorentin Labbe static int crypto_dump_report_done(struct netlink_callback *cb) 252cac5818cSCorentin Labbe { 253cac5818cSCorentin Labbe return 0; 254cac5818cSCorentin Labbe } 255cac5818cSCorentin Labbe 256cac5818cSCorentin Labbe static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 257cac5818cSCorentin Labbe struct nlattr **attrs) 258cac5818cSCorentin Labbe { 259cac5818cSCorentin Labbe struct crypto_alg *alg; 260cac5818cSCorentin Labbe struct crypto_user_alg *p = nlmsg_data(nlh); 261cac5818cSCorentin Labbe struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; 262cac5818cSCorentin Labbe LIST_HEAD(list); 263cac5818cSCorentin Labbe 264cac5818cSCorentin Labbe if (!netlink_capable(skb, CAP_NET_ADMIN)) 265cac5818cSCorentin Labbe return -EPERM; 266cac5818cSCorentin Labbe 267cac5818cSCorentin Labbe if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 268cac5818cSCorentin Labbe return -EINVAL; 269cac5818cSCorentin Labbe 270cac5818cSCorentin Labbe if (priority && !strlen(p->cru_driver_name)) 271cac5818cSCorentin Labbe return -EINVAL; 272cac5818cSCorentin Labbe 273cac5818cSCorentin Labbe alg = crypto_alg_match(p, 1); 274cac5818cSCorentin Labbe if (!alg) 275cac5818cSCorentin Labbe return -ENOENT; 276cac5818cSCorentin Labbe 277cac5818cSCorentin Labbe down_write(&crypto_alg_sem); 278cac5818cSCorentin Labbe 279cac5818cSCorentin Labbe crypto_remove_spawns(alg, &list, NULL); 280cac5818cSCorentin Labbe 281cac5818cSCorentin Labbe if (priority) 282cac5818cSCorentin Labbe alg->cra_priority = nla_get_u32(priority); 283cac5818cSCorentin Labbe 284cac5818cSCorentin Labbe up_write(&crypto_alg_sem); 285cac5818cSCorentin Labbe 286cac5818cSCorentin Labbe crypto_mod_put(alg); 287cac5818cSCorentin Labbe crypto_remove_final(&list); 288cac5818cSCorentin Labbe 289cac5818cSCorentin Labbe return 0; 290cac5818cSCorentin Labbe } 291cac5818cSCorentin Labbe 292cac5818cSCorentin Labbe static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 293cac5818cSCorentin Labbe struct nlattr **attrs) 294cac5818cSCorentin Labbe { 295cac5818cSCorentin Labbe struct crypto_alg *alg; 296cac5818cSCorentin Labbe struct crypto_user_alg *p = nlmsg_data(nlh); 297cac5818cSCorentin Labbe int err; 298cac5818cSCorentin Labbe 299cac5818cSCorentin Labbe if (!netlink_capable(skb, CAP_NET_ADMIN)) 300cac5818cSCorentin Labbe return -EPERM; 301cac5818cSCorentin Labbe 302cac5818cSCorentin Labbe if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 303cac5818cSCorentin Labbe return -EINVAL; 304cac5818cSCorentin Labbe 305cac5818cSCorentin Labbe alg = crypto_alg_match(p, 1); 306cac5818cSCorentin Labbe if (!alg) 307cac5818cSCorentin Labbe return -ENOENT; 308cac5818cSCorentin Labbe 309cac5818cSCorentin Labbe /* We can not unregister core algorithms such as aes-generic. 310cac5818cSCorentin Labbe * We would loose the reference in the crypto_alg_list to this algorithm 311cac5818cSCorentin Labbe * if we try to unregister. Unregistering such an algorithm without 312cac5818cSCorentin Labbe * removing the module is not possible, so we restrict to crypto 313cac5818cSCorentin Labbe * instances that are build from templates. */ 314cac5818cSCorentin Labbe err = -EINVAL; 315cac5818cSCorentin Labbe if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE)) 316cac5818cSCorentin Labbe goto drop_alg; 317cac5818cSCorentin Labbe 318cac5818cSCorentin Labbe err = -EBUSY; 319cac5818cSCorentin Labbe if (refcount_read(&alg->cra_refcnt) > 2) 320cac5818cSCorentin Labbe goto drop_alg; 321cac5818cSCorentin Labbe 322cac5818cSCorentin Labbe err = crypto_unregister_instance((struct crypto_instance *)alg); 323cac5818cSCorentin Labbe 324cac5818cSCorentin Labbe drop_alg: 325cac5818cSCorentin Labbe crypto_mod_put(alg); 326cac5818cSCorentin Labbe return err; 327cac5818cSCorentin Labbe } 328cac5818cSCorentin Labbe 329cac5818cSCorentin Labbe static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 330cac5818cSCorentin Labbe struct nlattr **attrs) 331cac5818cSCorentin Labbe { 332cac5818cSCorentin Labbe int exact = 0; 333cac5818cSCorentin Labbe const char *name; 334cac5818cSCorentin Labbe struct crypto_alg *alg; 335cac5818cSCorentin Labbe struct crypto_user_alg *p = nlmsg_data(nlh); 336cac5818cSCorentin Labbe struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; 337cac5818cSCorentin Labbe 338cac5818cSCorentin Labbe if (!netlink_capable(skb, CAP_NET_ADMIN)) 339cac5818cSCorentin Labbe return -EPERM; 340cac5818cSCorentin Labbe 341cac5818cSCorentin Labbe if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 342cac5818cSCorentin Labbe return -EINVAL; 343cac5818cSCorentin Labbe 344cac5818cSCorentin Labbe if (strlen(p->cru_driver_name)) 345cac5818cSCorentin Labbe exact = 1; 346cac5818cSCorentin Labbe 347cac5818cSCorentin Labbe if (priority && !exact) 348cac5818cSCorentin Labbe return -EINVAL; 349cac5818cSCorentin Labbe 350cac5818cSCorentin Labbe alg = crypto_alg_match(p, exact); 351cac5818cSCorentin Labbe if (alg) { 352cac5818cSCorentin Labbe crypto_mod_put(alg); 353cac5818cSCorentin Labbe return -EEXIST; 354cac5818cSCorentin Labbe } 355cac5818cSCorentin Labbe 356cac5818cSCorentin Labbe if (strlen(p->cru_driver_name)) 357cac5818cSCorentin Labbe name = p->cru_driver_name; 358cac5818cSCorentin Labbe else 359cac5818cSCorentin Labbe name = p->cru_name; 360cac5818cSCorentin Labbe 361cac5818cSCorentin Labbe alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); 362cac5818cSCorentin Labbe if (IS_ERR(alg)) 363cac5818cSCorentin Labbe return PTR_ERR(alg); 364cac5818cSCorentin Labbe 365cac5818cSCorentin Labbe down_write(&crypto_alg_sem); 366cac5818cSCorentin Labbe 367cac5818cSCorentin Labbe if (priority) 368cac5818cSCorentin Labbe alg->cra_priority = nla_get_u32(priority); 369cac5818cSCorentin Labbe 370cac5818cSCorentin Labbe up_write(&crypto_alg_sem); 371cac5818cSCorentin Labbe 372cac5818cSCorentin Labbe crypto_mod_put(alg); 373cac5818cSCorentin Labbe 374cac5818cSCorentin Labbe return 0; 375cac5818cSCorentin Labbe } 376cac5818cSCorentin Labbe 377cac5818cSCorentin Labbe static int crypto_del_rng(struct sk_buff *skb, struct nlmsghdr *nlh, 378cac5818cSCorentin Labbe struct nlattr **attrs) 379cac5818cSCorentin Labbe { 380cac5818cSCorentin Labbe if (!netlink_capable(skb, CAP_NET_ADMIN)) 381cac5818cSCorentin Labbe return -EPERM; 382cac5818cSCorentin Labbe return crypto_del_default_rng(); 383cac5818cSCorentin Labbe } 384cac5818cSCorentin Labbe 385cac5818cSCorentin Labbe #define MSGSIZE(type) sizeof(struct type) 386cac5818cSCorentin Labbe 387cac5818cSCorentin Labbe static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = { 388cac5818cSCorentin Labbe [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 389cac5818cSCorentin Labbe [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 390cac5818cSCorentin Labbe [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 391cac5818cSCorentin Labbe [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 392cac5818cSCorentin Labbe [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = 0, 393cac5818cSCorentin Labbe [CRYPTO_MSG_GETSTAT - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 394cac5818cSCorentin Labbe }; 395cac5818cSCorentin Labbe 396cac5818cSCorentin Labbe static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = { 397cac5818cSCorentin Labbe [CRYPTOCFGA_PRIORITY_VAL] = { .type = NLA_U32}, 398cac5818cSCorentin Labbe }; 399cac5818cSCorentin Labbe 400cac5818cSCorentin Labbe #undef MSGSIZE 401cac5818cSCorentin Labbe 402cac5818cSCorentin Labbe static const struct crypto_link { 403cac5818cSCorentin Labbe int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); 404cac5818cSCorentin Labbe int (*dump)(struct sk_buff *, struct netlink_callback *); 405cac5818cSCorentin Labbe int (*done)(struct netlink_callback *); 406cac5818cSCorentin Labbe } crypto_dispatch[CRYPTO_NR_MSGTYPES] = { 407cac5818cSCorentin Labbe [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = { .doit = crypto_add_alg}, 408cac5818cSCorentin Labbe [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = { .doit = crypto_del_alg}, 409cac5818cSCorentin Labbe [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = { .doit = crypto_update_alg}, 410cac5818cSCorentin Labbe [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = { .doit = crypto_report, 411cac5818cSCorentin Labbe .dump = crypto_dump_report, 412cac5818cSCorentin Labbe .done = crypto_dump_report_done}, 413cac5818cSCorentin Labbe [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng }, 4140c99c2a0SCorentin Labbe [CRYPTO_MSG_GETSTAT - CRYPTO_MSG_BASE] = { .doit = crypto_reportstat}, 415cac5818cSCorentin Labbe }; 416cac5818cSCorentin Labbe 417cac5818cSCorentin Labbe static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 418cac5818cSCorentin Labbe struct netlink_ext_ack *extack) 419cac5818cSCorentin Labbe { 420cac5818cSCorentin Labbe struct nlattr *attrs[CRYPTOCFGA_MAX+1]; 421cac5818cSCorentin Labbe const struct crypto_link *link; 422cac5818cSCorentin Labbe int type, err; 423cac5818cSCorentin Labbe 424cac5818cSCorentin Labbe type = nlh->nlmsg_type; 425cac5818cSCorentin Labbe if (type > CRYPTO_MSG_MAX) 426cac5818cSCorentin Labbe return -EINVAL; 427cac5818cSCorentin Labbe 428cac5818cSCorentin Labbe type -= CRYPTO_MSG_BASE; 429cac5818cSCorentin Labbe link = &crypto_dispatch[type]; 430cac5818cSCorentin Labbe 431cac5818cSCorentin Labbe if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && 432cac5818cSCorentin Labbe (nlh->nlmsg_flags & NLM_F_DUMP))) { 433cac5818cSCorentin Labbe struct crypto_alg *alg; 4340ac6b8fbSEric Biggers unsigned long dump_alloc = 0; 435cac5818cSCorentin Labbe 436cac5818cSCorentin Labbe if (link->dump == NULL) 437cac5818cSCorentin Labbe return -EINVAL; 438cac5818cSCorentin Labbe 439cac5818cSCorentin Labbe down_read(&crypto_alg_sem); 440cac5818cSCorentin Labbe list_for_each_entry(alg, &crypto_alg_list, cra_list) 441cac5818cSCorentin Labbe dump_alloc += CRYPTO_REPORT_MAXSIZE; 4420ac6b8fbSEric Biggers up_read(&crypto_alg_sem); 443cac5818cSCorentin Labbe 444cac5818cSCorentin Labbe { 445cac5818cSCorentin Labbe struct netlink_dump_control c = { 446cac5818cSCorentin Labbe .dump = link->dump, 447cac5818cSCorentin Labbe .done = link->done, 4480ac6b8fbSEric Biggers .min_dump_alloc = min(dump_alloc, 65535UL), 449cac5818cSCorentin Labbe }; 450cac5818cSCorentin Labbe err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); 451cac5818cSCorentin Labbe } 452cac5818cSCorentin Labbe 453cac5818cSCorentin Labbe return err; 454cac5818cSCorentin Labbe } 455cac5818cSCorentin Labbe 4568cb08174SJohannes Berg err = nlmsg_parse_deprecated(nlh, crypto_msg_min[type], attrs, 4578cb08174SJohannes Berg CRYPTOCFGA_MAX, crypto_policy, extack); 458cac5818cSCorentin Labbe if (err < 0) 459cac5818cSCorentin Labbe return err; 460cac5818cSCorentin Labbe 461cac5818cSCorentin Labbe if (link->doit == NULL) 462cac5818cSCorentin Labbe return -EINVAL; 463cac5818cSCorentin Labbe 464cac5818cSCorentin Labbe return link->doit(skb, nlh, attrs); 465cac5818cSCorentin Labbe } 466cac5818cSCorentin Labbe 467cac5818cSCorentin Labbe static void crypto_netlink_rcv(struct sk_buff *skb) 468cac5818cSCorentin Labbe { 469cac5818cSCorentin Labbe mutex_lock(&crypto_cfg_mutex); 470cac5818cSCorentin Labbe netlink_rcv_skb(skb, &crypto_user_rcv_msg); 471cac5818cSCorentin Labbe mutex_unlock(&crypto_cfg_mutex); 472cac5818cSCorentin Labbe } 473cac5818cSCorentin Labbe 474cac5818cSCorentin Labbe static int __init crypto_user_init(void) 475cac5818cSCorentin Labbe { 476cac5818cSCorentin Labbe struct netlink_kernel_cfg cfg = { 477cac5818cSCorentin Labbe .input = crypto_netlink_rcv, 478cac5818cSCorentin Labbe }; 479cac5818cSCorentin Labbe 480cac5818cSCorentin Labbe crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg); 481cac5818cSCorentin Labbe if (!crypto_nlsk) 482cac5818cSCorentin Labbe return -ENOMEM; 483cac5818cSCorentin Labbe 484cac5818cSCorentin Labbe return 0; 485cac5818cSCorentin Labbe } 486cac5818cSCorentin Labbe 487cac5818cSCorentin Labbe static void __exit crypto_user_exit(void) 488cac5818cSCorentin Labbe { 489cac5818cSCorentin Labbe netlink_kernel_release(crypto_nlsk); 490cac5818cSCorentin Labbe } 491cac5818cSCorentin Labbe 492cac5818cSCorentin Labbe module_init(crypto_user_init); 493cac5818cSCorentin Labbe module_exit(crypto_user_exit); 494cac5818cSCorentin Labbe MODULE_LICENSE("GPL"); 495cac5818cSCorentin Labbe MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); 496cac5818cSCorentin Labbe MODULE_DESCRIPTION("Crypto userspace configuration API"); 497cac5818cSCorentin Labbe MODULE_ALIAS("net-pf-16-proto-21"); 498