~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/crypto/crypto_user.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /crypto/crypto_user.c (Version linux-6.12-rc7) and /crypto/crypto_user.c (Version linux-4.14.336)


  1 // SPDX-License-Identifier: GPL-2.0-only       << 
  2 /*                                                  1 /*
  3  * Crypto user configuration API.                   2  * Crypto user configuration API.
  4  *                                                  3  *
  5  * Copyright (C) 2011 secunet Security Network      4  * Copyright (C) 2011 secunet Security Networks AG
  6  * Copyright (C) 2011 Steffen Klassert <steffe      5  * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com>
                                                   >>   6  *
                                                   >>   7  * This program is free software; you can redistribute it and/or modify it
                                                   >>   8  * under the terms and conditions of the GNU General Public License,
                                                   >>   9  * version 2, as published by the Free Software Foundation.
                                                   >>  10  *
                                                   >>  11  * This program is distributed in the hope it will be useful, but WITHOUT
                                                   >>  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                                   >>  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
                                                   >>  14  * more details.
                                                   >>  15  *
                                                   >>  16  * You should have received a copy of the GNU General Public License along with
                                                   >>  17  * this program; if not, write to the Free Software Foundation, Inc.,
                                                   >>  18  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  7  */                                                19  */
  8                                                    20 
  9 #include <linux/module.h>                          21 #include <linux/module.h>
 10 #include <linux/crypto.h>                          22 #include <linux/crypto.h>
 11 #include <linux/cryptouser.h>                      23 #include <linux/cryptouser.h>
 12 #include <linux/sched.h>                           24 #include <linux/sched.h>
 13 #include <linux/security.h>                    << 
 14 #include <net/netlink.h>                           25 #include <net/netlink.h>
                                                   >>  26 #include <linux/security.h>
 15 #include <net/net_namespace.h>                     27 #include <net/net_namespace.h>
 16 #include <net/sock.h>                          << 
 17 #include <crypto/internal/skcipher.h>              28 #include <crypto/internal/skcipher.h>
 18 #include <crypto/internal/rng.h>                   29 #include <crypto/internal/rng.h>
 19 #include <crypto/akcipher.h>                       30 #include <crypto/akcipher.h>
 20 #include <crypto/kpp.h>                            31 #include <crypto/kpp.h>
 21                                                    32 
 22 #include "internal.h"                              33 #include "internal.h"
 23                                                    34 
 24 #define null_terminated(x)      (strnlen(x, si     35 #define null_terminated(x)      (strnlen(x, sizeof(x)) < sizeof(x))
 25                                                    36 
 26 static DEFINE_MUTEX(crypto_cfg_mutex);             37 static DEFINE_MUTEX(crypto_cfg_mutex);
 27                                                    38 
                                                   >>  39 /* The crypto netlink socket */
                                                   >>  40 static struct sock *crypto_nlsk;
                                                   >>  41 
 28 struct crypto_dump_info {                          42 struct crypto_dump_info {
 29         struct sk_buff *in_skb;                    43         struct sk_buff *in_skb;
 30         struct sk_buff *out_skb;                   44         struct sk_buff *out_skb;
 31         u32 nlmsg_seq;                             45         u32 nlmsg_seq;
 32         u16 nlmsg_flags;                           46         u16 nlmsg_flags;
 33 };                                                 47 };
 34                                                    48 
 35 static struct crypto_alg *crypto_alg_match(str     49 static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
 36 {                                                  50 {
 37         struct crypto_alg *q, *alg = NULL;         51         struct crypto_alg *q, *alg = NULL;
 38                                                    52 
 39         down_read(&crypto_alg_sem);                53         down_read(&crypto_alg_sem);
 40                                                    54 
 41         list_for_each_entry(q, &crypto_alg_lis     55         list_for_each_entry(q, &crypto_alg_list, cra_list) {
 42                 int match = 0;                     56                 int match = 0;
 43                                                    57 
 44                 if (crypto_is_larval(q))           58                 if (crypto_is_larval(q))
 45                         continue;                  59                         continue;
 46                                                    60 
 47                 if ((q->cra_flags ^ p->cru_typ     61                 if ((q->cra_flags ^ p->cru_type) & p->cru_mask)
 48                         continue;                  62                         continue;
 49                                                    63 
 50                 if (strlen(p->cru_driver_name)     64                 if (strlen(p->cru_driver_name))
 51                         match = !strcmp(q->cra     65                         match = !strcmp(q->cra_driver_name,
 52                                         p->cru     66                                         p->cru_driver_name);
 53                 else if (!exact)                   67                 else if (!exact)
 54                         match = !strcmp(q->cra     68                         match = !strcmp(q->cra_name, p->cru_name);
 55                                                    69 
 56                 if (!match)                        70                 if (!match)
 57                         continue;                  71                         continue;
 58                                                    72 
 59                 if (unlikely(!crypto_mod_get(q     73                 if (unlikely(!crypto_mod_get(q)))
 60                         continue;                  74                         continue;
 61                                                    75 
 62                 alg = q;                           76                 alg = q;
 63                 break;                             77                 break;
 64         }                                          78         }
 65                                                    79 
 66         up_read(&crypto_alg_sem);                  80         up_read(&crypto_alg_sem);
 67                                                    81 
 68         return alg;                                82         return alg;
 69 }                                                  83 }
 70                                                    84 
 71 static int crypto_report_cipher(struct sk_buff     85 static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
 72 {                                                  86 {
 73         struct crypto_report_cipher rcipher;       87         struct crypto_report_cipher rcipher;
 74                                                    88 
 75         memset(&rcipher, 0, sizeof(rcipher));  !!  89         strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
 76                                                << 
 77         strscpy(rcipher.type, "cipher", sizeof << 
 78                                                    90 
 79         rcipher.blocksize = alg->cra_blocksize     91         rcipher.blocksize = alg->cra_blocksize;
 80         rcipher.min_keysize = alg->cra_cipher.     92         rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
 81         rcipher.max_keysize = alg->cra_cipher.     93         rcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
 82                                                    94 
 83         return nla_put(skb, CRYPTOCFGA_REPORT_ !!  95         if (nla_put(skb, CRYPTOCFGA_REPORT_CIPHER,
 84                        sizeof(rcipher), &rciph !!  96                     sizeof(struct crypto_report_cipher), &rcipher))
                                                   >>  97                 goto nla_put_failure;
                                                   >>  98         return 0;
                                                   >>  99 
                                                   >> 100 nla_put_failure:
                                                   >> 101         return -EMSGSIZE;
 85 }                                                 102 }
 86                                                   103 
 87 static int crypto_report_comp(struct sk_buff *    104 static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
 88 {                                                 105 {
 89         struct crypto_report_comp rcomp;          106         struct crypto_report_comp rcomp;
 90                                                   107 
 91         memset(&rcomp, 0, sizeof(rcomp));      !! 108         strncpy(rcomp.type, "compression", sizeof(rcomp.type));
                                                   >> 109         if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
                                                   >> 110                     sizeof(struct crypto_report_comp), &rcomp))
                                                   >> 111                 goto nla_put_failure;
                                                   >> 112         return 0;
                                                   >> 113 
                                                   >> 114 nla_put_failure:
                                                   >> 115         return -EMSGSIZE;
                                                   >> 116 }
                                                   >> 117 
                                                   >> 118 static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)
                                                   >> 119 {
                                                   >> 120         struct crypto_report_acomp racomp;
                                                   >> 121 
                                                   >> 122         strncpy(racomp.type, "acomp", sizeof(racomp.type));
                                                   >> 123 
                                                   >> 124         if (nla_put(skb, CRYPTOCFGA_REPORT_ACOMP,
                                                   >> 125                     sizeof(struct crypto_report_acomp), &racomp))
                                                   >> 126                 goto nla_put_failure;
                                                   >> 127         return 0;
                                                   >> 128 
                                                   >> 129 nla_put_failure:
                                                   >> 130         return -EMSGSIZE;
                                                   >> 131 }
                                                   >> 132 
                                                   >> 133 static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
                                                   >> 134 {
                                                   >> 135         struct crypto_report_akcipher rakcipher;
                                                   >> 136 
                                                   >> 137         strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
                                                   >> 138 
                                                   >> 139         if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
                                                   >> 140                     sizeof(struct crypto_report_akcipher), &rakcipher))
                                                   >> 141                 goto nla_put_failure;
                                                   >> 142         return 0;
                                                   >> 143 
                                                   >> 144 nla_put_failure:
                                                   >> 145         return -EMSGSIZE;
                                                   >> 146 }
 92                                                   147 
 93         strscpy(rcomp.type, "compression", siz !! 148 static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
                                                   >> 149 {
                                                   >> 150         struct crypto_report_kpp rkpp;
                                                   >> 151 
                                                   >> 152         strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
                                                   >> 153 
                                                   >> 154         if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
                                                   >> 155                     sizeof(struct crypto_report_kpp), &rkpp))
                                                   >> 156                 goto nla_put_failure;
                                                   >> 157         return 0;
 94                                                   158 
 95         return nla_put(skb, CRYPTOCFGA_REPORT_ !! 159 nla_put_failure:
                                                   >> 160         return -EMSGSIZE;
 96 }                                                 161 }
 97                                                   162 
 98 static int crypto_report_one(struct crypto_alg    163 static int crypto_report_one(struct crypto_alg *alg,
 99                              struct crypto_use    164                              struct crypto_user_alg *ualg, struct sk_buff *skb)
100 {                                                 165 {
101         memset(ualg, 0, sizeof(*ualg));        !! 166         strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
102                                                !! 167         strncpy(ualg->cru_driver_name, alg->cra_driver_name,
103         strscpy(ualg->cru_name, alg->cra_name, << 
104         strscpy(ualg->cru_driver_name, alg->cr << 
105                 sizeof(ualg->cru_driver_name))    168                 sizeof(ualg->cru_driver_name));
106         strscpy(ualg->cru_module_name, module_ !! 169         strncpy(ualg->cru_module_name, module_name(alg->cra_module),
107                 sizeof(ualg->cru_module_name))    170                 sizeof(ualg->cru_module_name));
108                                                   171 
109         ualg->cru_type = 0;                       172         ualg->cru_type = 0;
110         ualg->cru_mask = 0;                       173         ualg->cru_mask = 0;
111         ualg->cru_flags = alg->cra_flags;         174         ualg->cru_flags = alg->cra_flags;
112         ualg->cru_refcnt = refcount_read(&alg- !! 175         ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
113                                                   176 
114         if (nla_put_u32(skb, CRYPTOCFGA_PRIORI    177         if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority))
115                 goto nla_put_failure;             178                 goto nla_put_failure;
116         if (alg->cra_flags & CRYPTO_ALG_LARVAL    179         if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
117                 struct crypto_report_larval rl    180                 struct crypto_report_larval rl;
118                                                   181 
119                 memset(&rl, 0, sizeof(rl));    !! 182                 strncpy(rl.type, "larval", sizeof(rl.type));
120                 strscpy(rl.type, "larval", siz !! 183                 if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
121                 if (nla_put(skb, CRYPTOCFGA_RE !! 184                             sizeof(struct crypto_report_larval), &rl))
122                         goto nla_put_failure;     185                         goto nla_put_failure;
123                 goto out;                         186                 goto out;
124         }                                         187         }
125                                                   188 
126         if (alg->cra_type && alg->cra_type->re    189         if (alg->cra_type && alg->cra_type->report) {
127                 if (alg->cra_type->report(skb,    190                 if (alg->cra_type->report(skb, alg))
128                         goto nla_put_failure;     191                         goto nla_put_failure;
129                                                   192 
130                 goto out;                         193                 goto out;
131         }                                         194         }
132                                                   195 
133         switch (alg->cra_flags & (CRYPTO_ALG_T    196         switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
134         case CRYPTO_ALG_TYPE_CIPHER:              197         case CRYPTO_ALG_TYPE_CIPHER:
135                 if (crypto_report_cipher(skb,     198                 if (crypto_report_cipher(skb, alg))
136                         goto nla_put_failure;     199                         goto nla_put_failure;
137                                                   200 
138                 break;                            201                 break;
139         case CRYPTO_ALG_TYPE_COMPRESS:            202         case CRYPTO_ALG_TYPE_COMPRESS:
140                 if (crypto_report_comp(skb, al    203                 if (crypto_report_comp(skb, alg))
141                         goto nla_put_failure;     204                         goto nla_put_failure;
142                                                   205 
143                 break;                            206                 break;
                                                   >> 207         case CRYPTO_ALG_TYPE_ACOMPRESS:
                                                   >> 208                 if (crypto_report_acomp(skb, alg))
                                                   >> 209                         goto nla_put_failure;
                                                   >> 210 
                                                   >> 211                 break;
                                                   >> 212         case CRYPTO_ALG_TYPE_AKCIPHER:
                                                   >> 213                 if (crypto_report_akcipher(skb, alg))
                                                   >> 214                         goto nla_put_failure;
                                                   >> 215 
                                                   >> 216                 break;
                                                   >> 217         case CRYPTO_ALG_TYPE_KPP:
                                                   >> 218                 if (crypto_report_kpp(skb, alg))
                                                   >> 219                         goto nla_put_failure;
                                                   >> 220                 break;
144         }                                         221         }
145                                                   222 
146 out:                                              223 out:
147         return 0;                                 224         return 0;
148                                                   225 
149 nla_put_failure:                                  226 nla_put_failure:
150         return -EMSGSIZE;                         227         return -EMSGSIZE;
151 }                                                 228 }
152                                                   229 
153 static int crypto_report_alg(struct crypto_alg    230 static int crypto_report_alg(struct crypto_alg *alg,
154                              struct crypto_dum    231                              struct crypto_dump_info *info)
155 {                                                 232 {
156         struct sk_buff *in_skb = info->in_skb;    233         struct sk_buff *in_skb = info->in_skb;
157         struct sk_buff *skb = info->out_skb;      234         struct sk_buff *skb = info->out_skb;
158         struct nlmsghdr *nlh;                     235         struct nlmsghdr *nlh;
159         struct crypto_user_alg *ualg;             236         struct crypto_user_alg *ualg;
160         int err = 0;                              237         int err = 0;
161                                                   238 
162         nlh = nlmsg_put(skb, NETLINK_CB(in_skb    239         nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq,
163                         CRYPTO_MSG_GETALG, siz    240                         CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags);
164         if (!nlh) {                               241         if (!nlh) {
165                 err = -EMSGSIZE;                  242                 err = -EMSGSIZE;
166                 goto out;                         243                 goto out;
167         }                                         244         }
168                                                   245 
169         ualg = nlmsg_data(nlh);                   246         ualg = nlmsg_data(nlh);
170                                                   247 
171         err = crypto_report_one(alg, ualg, skb    248         err = crypto_report_one(alg, ualg, skb);
172         if (err) {                                249         if (err) {
173                 nlmsg_cancel(skb, nlh);           250                 nlmsg_cancel(skb, nlh);
174                 goto out;                         251                 goto out;
175         }                                         252         }
176                                                   253 
177         nlmsg_end(skb, nlh);                      254         nlmsg_end(skb, nlh);
178                                                   255 
179 out:                                              256 out:
180         return err;                               257         return err;
181 }                                                 258 }
182                                                   259 
183 static int crypto_report(struct sk_buff *in_sk    260 static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
184                          struct nlattr **attrs    261                          struct nlattr **attrs)
185 {                                                 262 {
186         struct net *net = sock_net(in_skb->sk) << 
187         struct crypto_user_alg *p = nlmsg_data    263         struct crypto_user_alg *p = nlmsg_data(in_nlh);
188         struct crypto_alg *alg;                   264         struct crypto_alg *alg;
189         struct sk_buff *skb;                      265         struct sk_buff *skb;
190         struct crypto_dump_info info;             266         struct crypto_dump_info info;
191         int err;                                  267         int err;
192                                                   268 
193         if (!null_terminated(p->cru_name) || !    269         if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
194                 return -EINVAL;                   270                 return -EINVAL;
195                                                   271 
196         alg = crypto_alg_match(p, 0);             272         alg = crypto_alg_match(p, 0);
197         if (!alg)                                 273         if (!alg)
198                 return -ENOENT;                   274                 return -ENOENT;
199                                                   275 
200         err = -ENOMEM;                            276         err = -ENOMEM;
201         skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GF !! 277         skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
202         if (!skb)                                 278         if (!skb)
203                 goto drop_alg;                    279                 goto drop_alg;
204                                                   280 
205         info.in_skb = in_skb;                     281         info.in_skb = in_skb;
206         info.out_skb = skb;                       282         info.out_skb = skb;
207         info.nlmsg_seq = in_nlh->nlmsg_seq;       283         info.nlmsg_seq = in_nlh->nlmsg_seq;
208         info.nlmsg_flags = 0;                     284         info.nlmsg_flags = 0;
209                                                   285 
210         err = crypto_report_alg(alg, &info);      286         err = crypto_report_alg(alg, &info);
211                                                   287 
212 drop_alg:                                         288 drop_alg:
213         crypto_mod_put(alg);                      289         crypto_mod_put(alg);
214                                                   290 
215         if (err) {                                291         if (err) {
216                 kfree_skb(skb);                   292                 kfree_skb(skb);
217                 return err;                       293                 return err;
218         }                                         294         }
219                                                   295 
220         return nlmsg_unicast(net->crypto_nlsk, !! 296         return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
221 }                                                 297 }
222                                                   298 
223 static int crypto_dump_report(struct sk_buff *    299 static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
224 {                                                 300 {
225         const size_t start_pos = cb->args[0];     301         const size_t start_pos = cb->args[0];
226         size_t pos = 0;                           302         size_t pos = 0;
227         struct crypto_dump_info info;             303         struct crypto_dump_info info;
228         struct crypto_alg *alg;                   304         struct crypto_alg *alg;
229         int res;                                  305         int res;
230                                                   306 
231         info.in_skb = cb->skb;                    307         info.in_skb = cb->skb;
232         info.out_skb = skb;                       308         info.out_skb = skb;
233         info.nlmsg_seq = cb->nlh->nlmsg_seq;      309         info.nlmsg_seq = cb->nlh->nlmsg_seq;
234         info.nlmsg_flags = NLM_F_MULTI;           310         info.nlmsg_flags = NLM_F_MULTI;
235                                                   311 
236         down_read(&crypto_alg_sem);               312         down_read(&crypto_alg_sem);
237         list_for_each_entry(alg, &crypto_alg_l    313         list_for_each_entry(alg, &crypto_alg_list, cra_list) {
238                 if (pos >= start_pos) {           314                 if (pos >= start_pos) {
239                         res = crypto_report_al    315                         res = crypto_report_alg(alg, &info);
240                         if (res == -EMSGSIZE)     316                         if (res == -EMSGSIZE)
241                                 break;            317                                 break;
242                         if (res)                  318                         if (res)
243                                 goto out;         319                                 goto out;
244                 }                                 320                 }
245                 pos++;                            321                 pos++;
246         }                                         322         }
247         cb->args[0] = pos;                        323         cb->args[0] = pos;
248         res = skb->len;                           324         res = skb->len;
249 out:                                              325 out:
250         up_read(&crypto_alg_sem);                 326         up_read(&crypto_alg_sem);
251         return res;                               327         return res;
252 }                                                 328 }
253                                                   329 
254 static int crypto_dump_report_done(struct netl    330 static int crypto_dump_report_done(struct netlink_callback *cb)
255 {                                                 331 {
256         return 0;                                 332         return 0;
257 }                                                 333 }
258                                                   334 
259 static int crypto_update_alg(struct sk_buff *s    335 static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
260                              struct nlattr **a    336                              struct nlattr **attrs)
261 {                                                 337 {
262         struct crypto_alg *alg;                   338         struct crypto_alg *alg;
263         struct crypto_user_alg *p = nlmsg_data    339         struct crypto_user_alg *p = nlmsg_data(nlh);
264         struct nlattr *priority = attrs[CRYPTO    340         struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL];
265         LIST_HEAD(list);                          341         LIST_HEAD(list);
266                                                   342 
267         if (!netlink_capable(skb, CAP_NET_ADMI    343         if (!netlink_capable(skb, CAP_NET_ADMIN))
268                 return -EPERM;                    344                 return -EPERM;
269                                                   345 
270         if (!null_terminated(p->cru_name) || !    346         if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
271                 return -EINVAL;                   347                 return -EINVAL;
272                                                   348 
273         if (priority && !strlen(p->cru_driver_    349         if (priority && !strlen(p->cru_driver_name))
274                 return -EINVAL;                   350                 return -EINVAL;
275                                                   351 
276         alg = crypto_alg_match(p, 1);             352         alg = crypto_alg_match(p, 1);
277         if (!alg)                                 353         if (!alg)
278                 return -ENOENT;                   354                 return -ENOENT;
279                                                   355 
280         down_write(&crypto_alg_sem);              356         down_write(&crypto_alg_sem);
281                                                   357 
282         crypto_remove_spawns(alg, &list, NULL)    358         crypto_remove_spawns(alg, &list, NULL);
283                                                   359 
284         if (priority)                             360         if (priority)
285                 alg->cra_priority = nla_get_u3    361                 alg->cra_priority = nla_get_u32(priority);
286                                                   362 
287         up_write(&crypto_alg_sem);                363         up_write(&crypto_alg_sem);
288                                                   364 
289         crypto_mod_put(alg);                      365         crypto_mod_put(alg);
290         crypto_remove_final(&list);               366         crypto_remove_final(&list);
291                                                   367 
292         return 0;                                 368         return 0;
293 }                                                 369 }
294                                                   370 
295 static int crypto_del_alg(struct sk_buff *skb,    371 static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
296                           struct nlattr **attr    372                           struct nlattr **attrs)
297 {                                                 373 {
298         struct crypto_alg *alg;                   374         struct crypto_alg *alg;
299         struct crypto_user_alg *p = nlmsg_data    375         struct crypto_user_alg *p = nlmsg_data(nlh);
300         int err;                                  376         int err;
301                                                   377 
302         if (!netlink_capable(skb, CAP_NET_ADMI    378         if (!netlink_capable(skb, CAP_NET_ADMIN))
303                 return -EPERM;                    379                 return -EPERM;
304                                                   380 
305         if (!null_terminated(p->cru_name) || !    381         if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
306                 return -EINVAL;                   382                 return -EINVAL;
307                                                   383 
308         alg = crypto_alg_match(p, 1);             384         alg = crypto_alg_match(p, 1);
309         if (!alg)                                 385         if (!alg)
310                 return -ENOENT;                   386                 return -ENOENT;
311                                                   387 
312         /* We can not unregister core algorith    388         /* We can not unregister core algorithms such as aes-generic.
313          * We would loose the reference in the    389          * We would loose the reference in the crypto_alg_list to this algorithm
314          * if we try to unregister. Unregister    390          * if we try to unregister. Unregistering such an algorithm without
315          * removing the module is not possible    391          * removing the module is not possible, so we restrict to crypto
316          * instances that are build from templ    392          * instances that are build from templates. */
317         err = -EINVAL;                            393         err = -EINVAL;
318         if (!(alg->cra_flags & CRYPTO_ALG_INST    394         if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
319                 goto drop_alg;                    395                 goto drop_alg;
320                                                   396 
321         err = -EBUSY;                             397         err = -EBUSY;
322         if (refcount_read(&alg->cra_refcnt) >  !! 398         if (atomic_read(&alg->cra_refcnt) > 2)
323                 goto drop_alg;                    399                 goto drop_alg;
324                                                   400 
325         crypto_unregister_instance((struct cry !! 401         err = crypto_unregister_instance((struct crypto_instance *)alg);
326         err = 0;                               << 
327                                                   402 
328 drop_alg:                                         403 drop_alg:
329         crypto_mod_put(alg);                      404         crypto_mod_put(alg);
330         return err;                               405         return err;
331 }                                                 406 }
332                                                   407 
333 static int crypto_add_alg(struct sk_buff *skb,    408 static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
334                           struct nlattr **attr    409                           struct nlattr **attrs)
335 {                                                 410 {
336         int exact = 0;                            411         int exact = 0;
337         const char *name;                         412         const char *name;
338         struct crypto_alg *alg;                   413         struct crypto_alg *alg;
339         struct crypto_user_alg *p = nlmsg_data    414         struct crypto_user_alg *p = nlmsg_data(nlh);
340         struct nlattr *priority = attrs[CRYPTO    415         struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL];
341                                                   416 
342         if (!netlink_capable(skb, CAP_NET_ADMI    417         if (!netlink_capable(skb, CAP_NET_ADMIN))
343                 return -EPERM;                    418                 return -EPERM;
344                                                   419 
345         if (!null_terminated(p->cru_name) || !    420         if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name))
346                 return -EINVAL;                   421                 return -EINVAL;
347                                                   422 
348         if (strlen(p->cru_driver_name))           423         if (strlen(p->cru_driver_name))
349                 exact = 1;                        424                 exact = 1;
350                                                   425 
351         if (priority && !exact)                   426         if (priority && !exact)
352                 return -EINVAL;                   427                 return -EINVAL;
353                                                   428 
354         alg = crypto_alg_match(p, exact);         429         alg = crypto_alg_match(p, exact);
355         if (alg) {                                430         if (alg) {
356                 crypto_mod_put(alg);              431                 crypto_mod_put(alg);
357                 return -EEXIST;                   432                 return -EEXIST;
358         }                                         433         }
359                                                   434 
360         if (strlen(p->cru_driver_name))           435         if (strlen(p->cru_driver_name))
361                 name = p->cru_driver_name;        436                 name = p->cru_driver_name;
362         else                                      437         else
363                 name = p->cru_name;               438                 name = p->cru_name;
364                                                   439 
365         alg = crypto_alg_mod_lookup(name, p->c    440         alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
366         if (IS_ERR(alg))                          441         if (IS_ERR(alg))
367                 return PTR_ERR(alg);              442                 return PTR_ERR(alg);
368                                                   443 
369         down_write(&crypto_alg_sem);              444         down_write(&crypto_alg_sem);
370                                                   445 
371         if (priority)                             446         if (priority)
372                 alg->cra_priority = nla_get_u3    447                 alg->cra_priority = nla_get_u32(priority);
373                                                   448 
374         up_write(&crypto_alg_sem);                449         up_write(&crypto_alg_sem);
375                                                   450 
376         crypto_mod_put(alg);                      451         crypto_mod_put(alg);
377                                                   452 
378         return 0;                                 453         return 0;
379 }                                                 454 }
380                                                   455 
381 static int crypto_del_rng(struct sk_buff *skb,    456 static int crypto_del_rng(struct sk_buff *skb, struct nlmsghdr *nlh,
382                           struct nlattr **attr    457                           struct nlattr **attrs)
383 {                                                 458 {
384         if (!netlink_capable(skb, CAP_NET_ADMI    459         if (!netlink_capable(skb, CAP_NET_ADMIN))
385                 return -EPERM;                    460                 return -EPERM;
386         return crypto_del_default_rng();          461         return crypto_del_default_rng();
387 }                                                 462 }
388                                                   463 
389 static int crypto_reportstat(struct sk_buff *i << 
390                              struct nlattr **a << 
391 {                                              << 
392         /* No longer supported */              << 
393         return -ENOTSUPP;                      << 
394 }                                              << 
395                                                << 
396 #define MSGSIZE(type) sizeof(struct type)         464 #define MSGSIZE(type) sizeof(struct type)
397                                                   465 
398 static const int crypto_msg_min[CRYPTO_NR_MSGT    466 static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = {
399         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_B    467         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
400         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_B    468         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
401         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_B    469         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
402         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_B    470         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
403         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_B    471         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_BASE] = 0,
404         [CRYPTO_MSG_GETSTAT     - CRYPTO_MSG_B << 
405 };                                                472 };
406                                                   473 
407 static const struct nla_policy crypto_policy[C    474 static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = {
408         [CRYPTOCFGA_PRIORITY_VAL]   = { .type     475         [CRYPTOCFGA_PRIORITY_VAL]   = { .type = NLA_U32},
409 };                                                476 };
410                                                   477 
411 #undef MSGSIZE                                    478 #undef MSGSIZE
412                                                   479 
413 static const struct crypto_link {                 480 static const struct crypto_link {
414         int (*doit)(struct sk_buff *, struct n    481         int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
415         int (*dump)(struct sk_buff *, struct n    482         int (*dump)(struct sk_buff *, struct netlink_callback *);
416         int (*done)(struct netlink_callback *)    483         int (*done)(struct netlink_callback *);
417 } crypto_dispatch[CRYPTO_NR_MSGTYPES] = {         484 } crypto_dispatch[CRYPTO_NR_MSGTYPES] = {
418         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_B    485         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_BASE] = { .doit = crypto_add_alg},
419         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_B    486         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_BASE] = { .doit = crypto_del_alg},
420         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_B    487         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_BASE] = { .doit = crypto_update_alg},
421         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_B    488         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_BASE] = { .doit = crypto_report,
422                                                   489                                                        .dump = crypto_dump_report,
423                                                   490                                                        .done = crypto_dump_report_done},
424         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_B    491         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng },
425         [CRYPTO_MSG_GETSTAT     - CRYPTO_MSG_B << 
426 };                                                492 };
427                                                   493 
428 static int crypto_user_rcv_msg(struct sk_buff     494 static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
429                                struct netlink_    495                                struct netlink_ext_ack *extack)
430 {                                                 496 {
431         struct net *net = sock_net(skb->sk);   << 
432         struct nlattr *attrs[CRYPTOCFGA_MAX+1]    497         struct nlattr *attrs[CRYPTOCFGA_MAX+1];
433         const struct crypto_link *link;           498         const struct crypto_link *link;
434         int type, err;                            499         int type, err;
435                                                   500 
436         type = nlh->nlmsg_type;                   501         type = nlh->nlmsg_type;
437         if (type > CRYPTO_MSG_MAX)                502         if (type > CRYPTO_MSG_MAX)
438                 return -EINVAL;                   503                 return -EINVAL;
439                                                   504 
440         type -= CRYPTO_MSG_BASE;                  505         type -= CRYPTO_MSG_BASE;
441         link = &crypto_dispatch[type];            506         link = &crypto_dispatch[type];
442                                                   507 
443         if ((type == (CRYPTO_MSG_GETALG - CRYP    508         if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
444             (nlh->nlmsg_flags & NLM_F_DUMP)))     509             (nlh->nlmsg_flags & NLM_F_DUMP))) {
445                 struct crypto_alg *alg;           510                 struct crypto_alg *alg;
446                 unsigned long dump_alloc = 0;     511                 unsigned long dump_alloc = 0;
447                                                   512 
448                 if (link->dump == NULL)           513                 if (link->dump == NULL)
449                         return -EINVAL;           514                         return -EINVAL;
450                                                   515 
451                 down_read(&crypto_alg_sem);       516                 down_read(&crypto_alg_sem);
452                 list_for_each_entry(alg, &cryp    517                 list_for_each_entry(alg, &crypto_alg_list, cra_list)
453                         dump_alloc += CRYPTO_R    518                         dump_alloc += CRYPTO_REPORT_MAXSIZE;
454                 up_read(&crypto_alg_sem);         519                 up_read(&crypto_alg_sem);
455                                                   520 
456                 {                                 521                 {
457                         struct netlink_dump_co    522                         struct netlink_dump_control c = {
458                                 .dump = link->    523                                 .dump = link->dump,
459                                 .done = link->    524                                 .done = link->done,
460                                 .min_dump_allo    525                                 .min_dump_alloc = min(dump_alloc, 65535UL),
461                         };                        526                         };
462                         err = netlink_dump_sta !! 527                         err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
463                 }                                 528                 }
464                                                   529 
465                 return err;                       530                 return err;
466         }                                         531         }
467                                                   532 
468         err = nlmsg_parse_deprecated(nlh, cryp !! 533         err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
469                                      CRYPTOCFG !! 534                           crypto_policy, extack);
470         if (err < 0)                              535         if (err < 0)
471                 return err;                       536                 return err;
472                                                   537 
473         if (link->doit == NULL)                   538         if (link->doit == NULL)
474                 return -EINVAL;                   539                 return -EINVAL;
475                                                   540 
476         return link->doit(skb, nlh, attrs);       541         return link->doit(skb, nlh, attrs);
477 }                                                 542 }
478                                                   543 
479 static void crypto_netlink_rcv(struct sk_buff     544 static void crypto_netlink_rcv(struct sk_buff *skb)
480 {                                                 545 {
481         mutex_lock(&crypto_cfg_mutex);            546         mutex_lock(&crypto_cfg_mutex);
482         netlink_rcv_skb(skb, &crypto_user_rcv_    547         netlink_rcv_skb(skb, &crypto_user_rcv_msg);
483         mutex_unlock(&crypto_cfg_mutex);          548         mutex_unlock(&crypto_cfg_mutex);
484 }                                                 549 }
485                                                   550 
486 static int __net_init crypto_netlink_init(stru !! 551 static int __init crypto_user_init(void)
487 {                                                 552 {
488         struct netlink_kernel_cfg cfg = {         553         struct netlink_kernel_cfg cfg = {
489                 .input  = crypto_netlink_rcv,     554                 .input  = crypto_netlink_rcv,
490         };                                        555         };
491                                                   556 
492         net->crypto_nlsk = netlink_kernel_crea !! 557         crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
493         return net->crypto_nlsk == NULL ? -ENO !! 558         if (!crypto_nlsk)
494 }                                              !! 559                 return -ENOMEM;
495                                                   560 
496 static void __net_exit crypto_netlink_exit(str !! 561         return 0;
497 {                                              << 
498         netlink_kernel_release(net->crypto_nls << 
499         net->crypto_nlsk = NULL;               << 
500 }                                              << 
501                                                << 
502 static struct pernet_operations crypto_netlink << 
503         .init = crypto_netlink_init,           << 
504         .exit = crypto_netlink_exit,           << 
505 };                                             << 
506                                                << 
507 static int __init crypto_user_init(void)       << 
508 {                                              << 
509         return register_pernet_subsys(&crypto_ << 
510 }                                                 562 }
511                                                   563 
512 static void __exit crypto_user_exit(void)         564 static void __exit crypto_user_exit(void)
513 {                                                 565 {
514         unregister_pernet_subsys(&crypto_netli !! 566         netlink_kernel_release(crypto_nlsk);
515 }                                                 567 }
516                                                   568 
517 module_init(crypto_user_init);                    569 module_init(crypto_user_init);
518 module_exit(crypto_user_exit);                    570 module_exit(crypto_user_exit);
519 MODULE_LICENSE("GPL");                            571 MODULE_LICENSE("GPL");
520 MODULE_AUTHOR("Steffen Klassert <steffen.klass    572 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>");
521 MODULE_DESCRIPTION("Crypto userspace configura    573 MODULE_DESCRIPTION("Crypto userspace configuration API");
522 MODULE_ALIAS("net-pf-16-proto-21");               574 MODULE_ALIAS("net-pf-16-proto-21");
523                                                   575 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php