~ [ 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-5.13.19)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Crypto user configuration API.                 
  4  *                                                
  5  * Copyright (C) 2011 secunet Security Network    
  6  * Copyright (C) 2011 Steffen Klassert <steffe    
  7  */                                               
  8                                                   
  9 #include <linux/module.h>                         
 10 #include <linux/crypto.h>                         
 11 #include <linux/cryptouser.h>                     
 12 #include <linux/sched.h>                          
 13 #include <linux/security.h>                       
 14 #include <net/netlink.h>                          
 15 #include <net/net_namespace.h>                    
 16 #include <net/sock.h>                             
 17 #include <crypto/internal/skcipher.h>             
 18 #include <crypto/internal/rng.h>                  
 19 #include <crypto/akcipher.h>                      
 20 #include <crypto/kpp.h>                           
 21                                                   
 22 #include "internal.h"                             
 23                                                   
 24 #define null_terminated(x)      (strnlen(x, si    
 25                                                   
 26 static DEFINE_MUTEX(crypto_cfg_mutex);            
 27                                                   
 28 struct crypto_dump_info {                         
 29         struct sk_buff *in_skb;                   
 30         struct sk_buff *out_skb;                  
 31         u32 nlmsg_seq;                            
 32         u16 nlmsg_flags;                          
 33 };                                                
 34                                                   
 35 static struct crypto_alg *crypto_alg_match(str    
 36 {                                                 
 37         struct crypto_alg *q, *alg = NULL;        
 38                                                   
 39         down_read(&crypto_alg_sem);               
 40                                                   
 41         list_for_each_entry(q, &crypto_alg_lis    
 42                 int match = 0;                    
 43                                                   
 44                 if (crypto_is_larval(q))          
 45                         continue;                 
 46                                                   
 47                 if ((q->cra_flags ^ p->cru_typ    
 48                         continue;                 
 49                                                   
 50                 if (strlen(p->cru_driver_name)    
 51                         match = !strcmp(q->cra    
 52                                         p->cru    
 53                 else if (!exact)                  
 54                         match = !strcmp(q->cra    
 55                                                   
 56                 if (!match)                       
 57                         continue;                 
 58                                                   
 59                 if (unlikely(!crypto_mod_get(q    
 60                         continue;                 
 61                                                   
 62                 alg = q;                          
 63                 break;                            
 64         }                                         
 65                                                   
 66         up_read(&crypto_alg_sem);                 
 67                                                   
 68         return alg;                               
 69 }                                                 
 70                                                   
 71 static int crypto_report_cipher(struct sk_buff    
 72 {                                                 
 73         struct crypto_report_cipher rcipher;      
 74                                                   
 75         memset(&rcipher, 0, sizeof(rcipher));     
 76                                                   
 77         strscpy(rcipher.type, "cipher", sizeof    
 78                                                   
 79         rcipher.blocksize = alg->cra_blocksize    
 80         rcipher.min_keysize = alg->cra_cipher.    
 81         rcipher.max_keysize = alg->cra_cipher.    
 82                                                   
 83         return nla_put(skb, CRYPTOCFGA_REPORT_    
 84                        sizeof(rcipher), &rciph    
 85 }                                                 
 86                                                   
 87 static int crypto_report_comp(struct sk_buff *    
 88 {                                                 
 89         struct crypto_report_comp rcomp;          
 90                                                   
 91         memset(&rcomp, 0, sizeof(rcomp));         
 92                                                   
 93         strscpy(rcomp.type, "compression", siz    
 94                                                   
 95         return nla_put(skb, CRYPTOCFGA_REPORT_    
 96 }                                                 
 97                                                   
 98 static int crypto_report_one(struct crypto_alg    
 99                              struct crypto_use    
100 {                                                 
101         memset(ualg, 0, sizeof(*ualg));           
102                                                   
103         strscpy(ualg->cru_name, alg->cra_name,    
104         strscpy(ualg->cru_driver_name, alg->cr    
105                 sizeof(ualg->cru_driver_name))    
106         strscpy(ualg->cru_module_name, module_    
107                 sizeof(ualg->cru_module_name))    
108                                                   
109         ualg->cru_type = 0;                       
110         ualg->cru_mask = 0;                       
111         ualg->cru_flags = alg->cra_flags;         
112         ualg->cru_refcnt = refcount_read(&alg-    
113                                                   
114         if (nla_put_u32(skb, CRYPTOCFGA_PRIORI    
115                 goto nla_put_failure;             
116         if (alg->cra_flags & CRYPTO_ALG_LARVAL    
117                 struct crypto_report_larval rl    
118                                                   
119                 memset(&rl, 0, sizeof(rl));       
120                 strscpy(rl.type, "larval", siz    
121                 if (nla_put(skb, CRYPTOCFGA_RE    
122                         goto nla_put_failure;     
123                 goto out;                         
124         }                                         
125                                                   
126         if (alg->cra_type && alg->cra_type->re    
127                 if (alg->cra_type->report(skb,    
128                         goto nla_put_failure;     
129                                                   
130                 goto out;                         
131         }                                         
132                                                   
133         switch (alg->cra_flags & (CRYPTO_ALG_T    
134         case CRYPTO_ALG_TYPE_CIPHER:              
135                 if (crypto_report_cipher(skb,     
136                         goto nla_put_failure;     
137                                                   
138                 break;                            
139         case CRYPTO_ALG_TYPE_COMPRESS:            
140                 if (crypto_report_comp(skb, al    
141                         goto nla_put_failure;     
142                                                   
143                 break;                            
144         }                                         
145                                                   
146 out:                                              
147         return 0;                                 
148                                                   
149 nla_put_failure:                                  
150         return -EMSGSIZE;                         
151 }                                                 
152                                                   
153 static int crypto_report_alg(struct crypto_alg    
154                              struct crypto_dum    
155 {                                                 
156         struct sk_buff *in_skb = info->in_skb;    
157         struct sk_buff *skb = info->out_skb;      
158         struct nlmsghdr *nlh;                     
159         struct crypto_user_alg *ualg;             
160         int err = 0;                              
161                                                   
162         nlh = nlmsg_put(skb, NETLINK_CB(in_skb    
163                         CRYPTO_MSG_GETALG, siz    
164         if (!nlh) {                               
165                 err = -EMSGSIZE;                  
166                 goto out;                         
167         }                                         
168                                                   
169         ualg = nlmsg_data(nlh);                   
170                                                   
171         err = crypto_report_one(alg, ualg, skb    
172         if (err) {                                
173                 nlmsg_cancel(skb, nlh);           
174                 goto out;                         
175         }                                         
176                                                   
177         nlmsg_end(skb, nlh);                      
178                                                   
179 out:                                              
180         return err;                               
181 }                                                 
182                                                   
183 static int crypto_report(struct sk_buff *in_sk    
184                          struct nlattr **attrs    
185 {                                                 
186         struct net *net = sock_net(in_skb->sk)    
187         struct crypto_user_alg *p = nlmsg_data    
188         struct crypto_alg *alg;                   
189         struct sk_buff *skb;                      
190         struct crypto_dump_info info;             
191         int err;                                  
192                                                   
193         if (!null_terminated(p->cru_name) || !    
194                 return -EINVAL;                   
195                                                   
196         alg = crypto_alg_match(p, 0);             
197         if (!alg)                                 
198                 return -ENOENT;                   
199                                                   
200         err = -ENOMEM;                            
201         skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GF    
202         if (!skb)                                 
203                 goto drop_alg;                    
204                                                   
205         info.in_skb = in_skb;                     
206         info.out_skb = skb;                       
207         info.nlmsg_seq = in_nlh->nlmsg_seq;       
208         info.nlmsg_flags = 0;                     
209                                                   
210         err = crypto_report_alg(alg, &info);      
211                                                   
212 drop_alg:                                         
213         crypto_mod_put(alg);                      
214                                                   
215         if (err) {                                
216                 kfree_skb(skb);                   
217                 return err;                       
218         }                                         
219                                                   
220         return nlmsg_unicast(net->crypto_nlsk,    
221 }                                                 
222                                                   
223 static int crypto_dump_report(struct sk_buff *    
224 {                                                 
225         const size_t start_pos = cb->args[0];     
226         size_t pos = 0;                           
227         struct crypto_dump_info info;             
228         struct crypto_alg *alg;                   
229         int res;                                  
230                                                   
231         info.in_skb = cb->skb;                    
232         info.out_skb = skb;                       
233         info.nlmsg_seq = cb->nlh->nlmsg_seq;      
234         info.nlmsg_flags = NLM_F_MULTI;           
235                                                   
236         down_read(&crypto_alg_sem);               
237         list_for_each_entry(alg, &crypto_alg_l    
238                 if (pos >= start_pos) {           
239                         res = crypto_report_al    
240                         if (res == -EMSGSIZE)     
241                                 break;            
242                         if (res)                  
243                                 goto out;         
244                 }                                 
245                 pos++;                            
246         }                                         
247         cb->args[0] = pos;                        
248         res = skb->len;                           
249 out:                                              
250         up_read(&crypto_alg_sem);                 
251         return res;                               
252 }                                                 
253                                                   
254 static int crypto_dump_report_done(struct netl    
255 {                                                 
256         return 0;                                 
257 }                                                 
258                                                   
259 static int crypto_update_alg(struct sk_buff *s    
260                              struct nlattr **a    
261 {                                                 
262         struct crypto_alg *alg;                   
263         struct crypto_user_alg *p = nlmsg_data    
264         struct nlattr *priority = attrs[CRYPTO    
265         LIST_HEAD(list);                          
266                                                   
267         if (!netlink_capable(skb, CAP_NET_ADMI    
268                 return -EPERM;                    
269                                                   
270         if (!null_terminated(p->cru_name) || !    
271                 return -EINVAL;                   
272                                                   
273         if (priority && !strlen(p->cru_driver_    
274                 return -EINVAL;                   
275                                                   
276         alg = crypto_alg_match(p, 1);             
277         if (!alg)                                 
278                 return -ENOENT;                   
279                                                   
280         down_write(&crypto_alg_sem);              
281                                                   
282         crypto_remove_spawns(alg, &list, NULL)    
283                                                   
284         if (priority)                             
285                 alg->cra_priority = nla_get_u3    
286                                                   
287         up_write(&crypto_alg_sem);                
288                                                   
289         crypto_mod_put(alg);                      
290         crypto_remove_final(&list);               
291                                                   
292         return 0;                                 
293 }                                                 
294                                                   
295 static int crypto_del_alg(struct sk_buff *skb,    
296                           struct nlattr **attr    
297 {                                                 
298         struct crypto_alg *alg;                   
299         struct crypto_user_alg *p = nlmsg_data    
300         int err;                                  
301                                                   
302         if (!netlink_capable(skb, CAP_NET_ADMI    
303                 return -EPERM;                    
304                                                   
305         if (!null_terminated(p->cru_name) || !    
306                 return -EINVAL;                   
307                                                   
308         alg = crypto_alg_match(p, 1);             
309         if (!alg)                                 
310                 return -ENOENT;                   
311                                                   
312         /* We can not unregister core algorith    
313          * We would loose the reference in the    
314          * if we try to unregister. Unregister    
315          * removing the module is not possible    
316          * instances that are build from templ    
317         err = -EINVAL;                            
318         if (!(alg->cra_flags & CRYPTO_ALG_INST    
319                 goto drop_alg;                    
320                                                   
321         err = -EBUSY;                             
322         if (refcount_read(&alg->cra_refcnt) >     
323                 goto drop_alg;                    
324                                                   
325         crypto_unregister_instance((struct cry    
326         err = 0;                                  
327                                                   
328 drop_alg:                                         
329         crypto_mod_put(alg);                      
330         return err;                               
331 }                                                 
332                                                   
333 static int crypto_add_alg(struct sk_buff *skb,    
334                           struct nlattr **attr    
335 {                                                 
336         int exact = 0;                            
337         const char *name;                         
338         struct crypto_alg *alg;                   
339         struct crypto_user_alg *p = nlmsg_data    
340         struct nlattr *priority = attrs[CRYPTO    
341                                                   
342         if (!netlink_capable(skb, CAP_NET_ADMI    
343                 return -EPERM;                    
344                                                   
345         if (!null_terminated(p->cru_name) || !    
346                 return -EINVAL;                   
347                                                   
348         if (strlen(p->cru_driver_name))           
349                 exact = 1;                        
350                                                   
351         if (priority && !exact)                   
352                 return -EINVAL;                   
353                                                   
354         alg = crypto_alg_match(p, exact);         
355         if (alg) {                                
356                 crypto_mod_put(alg);              
357                 return -EEXIST;                   
358         }                                         
359                                                   
360         if (strlen(p->cru_driver_name))           
361                 name = p->cru_driver_name;        
362         else                                      
363                 name = p->cru_name;               
364                                                   
365         alg = crypto_alg_mod_lookup(name, p->c    
366         if (IS_ERR(alg))                          
367                 return PTR_ERR(alg);              
368                                                   
369         down_write(&crypto_alg_sem);              
370                                                   
371         if (priority)                             
372                 alg->cra_priority = nla_get_u3    
373                                                   
374         up_write(&crypto_alg_sem);                
375                                                   
376         crypto_mod_put(alg);                      
377                                                   
378         return 0;                                 
379 }                                                 
380                                                   
381 static int crypto_del_rng(struct sk_buff *skb,    
382                           struct nlattr **attr    
383 {                                                 
384         if (!netlink_capable(skb, CAP_NET_ADMI    
385                 return -EPERM;                    
386         return crypto_del_default_rng();          
387 }                                                 
388                                                   
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)         
397                                                   
398 static const int crypto_msg_min[CRYPTO_NR_MSGT    
399         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_B    
400         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_B    
401         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_B    
402         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_B    
403         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_B    
404         [CRYPTO_MSG_GETSTAT     - CRYPTO_MSG_B    
405 };                                                
406                                                   
407 static const struct nla_policy crypto_policy[C    
408         [CRYPTOCFGA_PRIORITY_VAL]   = { .type     
409 };                                                
410                                                   
411 #undef MSGSIZE                                    
412                                                   
413 static const struct crypto_link {                 
414         int (*doit)(struct sk_buff *, struct n    
415         int (*dump)(struct sk_buff *, struct n    
416         int (*done)(struct netlink_callback *)    
417 } crypto_dispatch[CRYPTO_NR_MSGTYPES] = {         
418         [CRYPTO_MSG_NEWALG      - CRYPTO_MSG_B    
419         [CRYPTO_MSG_DELALG      - CRYPTO_MSG_B    
420         [CRYPTO_MSG_UPDATEALG   - CRYPTO_MSG_B    
421         [CRYPTO_MSG_GETALG      - CRYPTO_MSG_B    
422                                                   
423                                                   
424         [CRYPTO_MSG_DELRNG      - CRYPTO_MSG_B    
425         [CRYPTO_MSG_GETSTAT     - CRYPTO_MSG_B    
426 };                                                
427                                                   
428 static int crypto_user_rcv_msg(struct sk_buff     
429                                struct netlink_    
430 {                                                 
431         struct net *net = sock_net(skb->sk);      
432         struct nlattr *attrs[CRYPTOCFGA_MAX+1]    
433         const struct crypto_link *link;           
434         int type, err;                            
435                                                   
436         type = nlh->nlmsg_type;                   
437         if (type > CRYPTO_MSG_MAX)                
438                 return -EINVAL;                   
439                                                   
440         type -= CRYPTO_MSG_BASE;                  
441         link = &crypto_dispatch[type];            
442                                                   
443         if ((type == (CRYPTO_MSG_GETALG - CRYP    
444             (nlh->nlmsg_flags & NLM_F_DUMP)))     
445                 struct crypto_alg *alg;           
446                 unsigned long dump_alloc = 0;     
447                                                   
448                 if (link->dump == NULL)           
449                         return -EINVAL;           
450                                                   
451                 down_read(&crypto_alg_sem);       
452                 list_for_each_entry(alg, &cryp    
453                         dump_alloc += CRYPTO_R    
454                 up_read(&crypto_alg_sem);         
455                                                   
456                 {                                 
457                         struct netlink_dump_co    
458                                 .dump = link->    
459                                 .done = link->    
460                                 .min_dump_allo    
461                         };                        
462                         err = netlink_dump_sta    
463                 }                                 
464                                                   
465                 return err;                       
466         }                                         
467                                                   
468         err = nlmsg_parse_deprecated(nlh, cryp    
469                                      CRYPTOCFG    
470         if (err < 0)                              
471                 return err;                       
472                                                   
473         if (link->doit == NULL)                   
474                 return -EINVAL;                   
475                                                   
476         return link->doit(skb, nlh, attrs);       
477 }                                                 
478                                                   
479 static void crypto_netlink_rcv(struct sk_buff     
480 {                                                 
481         mutex_lock(&crypto_cfg_mutex);            
482         netlink_rcv_skb(skb, &crypto_user_rcv_    
483         mutex_unlock(&crypto_cfg_mutex);          
484 }                                                 
485                                                   
486 static int __net_init crypto_netlink_init(stru    
487 {                                                 
488         struct netlink_kernel_cfg cfg = {         
489                 .input  = crypto_netlink_rcv,     
490         };                                        
491                                                   
492         net->crypto_nlsk = netlink_kernel_crea    
493         return net->crypto_nlsk == NULL ? -ENO    
494 }                                                 
495                                                   
496 static void __net_exit crypto_netlink_exit(str    
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 }                                                 
511                                                   
512 static void __exit crypto_user_exit(void)         
513 {                                                 
514         unregister_pernet_subsys(&crypto_netli    
515 }                                                 
516                                                   
517 module_init(crypto_user_init);                    
518 module_exit(crypto_user_exit);                    
519 MODULE_LICENSE("GPL");                            
520 MODULE_AUTHOR("Steffen Klassert <steffen.klass    
521 MODULE_DESCRIPTION("Crypto userspace configura    
522 MODULE_ALIAS("net-pf-16-proto-21");               
523                                                   

~ [ 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