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

TOMOYO Linux Cross Reference
Linux/crypto/algapi.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /crypto/algapi.c (Version linux-6.11.5) and /crypto/algapi.c (Version linux-5.10.223)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  * Cryptographic API for algorithms (i.e., low    
  4  *                                                
  5  * Copyright (c) 2006 Herbert Xu <herbert@gond    
  6  */                                               
  7                                                   
  8 #include <crypto/algapi.h>                        
  9 #include <crypto/internal/simd.h>                 
 10 #include <linux/err.h>                            
 11 #include <linux/errno.h>                          
 12 #include <linux/fips.h>                           
 13 #include <linux/init.h>                           
 14 #include <linux/kernel.h>                         
 15 #include <linux/list.h>                           
 16 #include <linux/module.h>                         
 17 #include <linux/rtnetlink.h>                      
 18 #include <linux/slab.h>                           
 19 #include <linux/string.h>                         
 20 #include <linux/workqueue.h>                      
 21                                                   
 22 #include "internal.h"                             
 23                                                   
 24 static LIST_HEAD(crypto_template_list);           
 25                                                   
 26 #ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS          
 27 DEFINE_PER_CPU(bool, crypto_simd_disabled_for_    
 28 EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled    
 29 #endif                                            
 30                                                   
 31 static inline void crypto_check_module_sig(str    
 32 {                                                 
 33         if (fips_enabled && mod && !module_sig    
 34                 panic("Module %s signature ver    
 35                       module_name(mod));          
 36 }                                                 
 37                                                   
 38 static int crypto_check_alg(struct crypto_alg     
 39 {                                                 
 40         crypto_check_module_sig(alg->cra_modul    
 41                                                   
 42         if (!alg->cra_name[0] || !alg->cra_dri    
 43                 return -EINVAL;                   
 44                                                   
 45         if (alg->cra_alignmask & (alg->cra_ali    
 46                 return -EINVAL;                   
 47                                                   
 48         /* General maximums for all algs. */      
 49         if (alg->cra_alignmask > MAX_ALGAPI_AL    
 50                 return -EINVAL;                   
 51                                                   
 52         if (alg->cra_blocksize > MAX_ALGAPI_BL    
 53                 return -EINVAL;                   
 54                                                   
 55         /* Lower maximums for specific alg typ    
 56         if (!alg->cra_type && (alg->cra_flags     
 57                                CRYPTO_ALG_TYPE    
 58                 if (alg->cra_alignmask > MAX_C    
 59                         return -EINVAL;           
 60                                                   
 61                 if (alg->cra_blocksize > MAX_C    
 62                         return -EINVAL;           
 63         }                                         
 64                                                   
 65         if (alg->cra_priority < 0)                
 66                 return -EINVAL;                   
 67                                                   
 68         refcount_set(&alg->cra_refcnt, 1);        
 69                                                   
 70         return 0;                                 
 71 }                                                 
 72                                                   
 73 static void crypto_free_instance(struct crypto    
 74 {                                                 
 75         inst->alg.cra_type->free(inst);           
 76 }                                                 
 77                                                   
 78 static void crypto_destroy_instance_workfn(str    
 79 {                                                 
 80         struct crypto_instance *inst = contain    
 81                                                   
 82         struct crypto_template *tmpl = inst->t    
 83                                                   
 84         crypto_free_instance(inst);               
 85         crypto_tmpl_put(tmpl);                    
 86 }                                                 
 87                                                   
 88 static void crypto_destroy_instance(struct cry    
 89 {                                                 
 90         struct crypto_instance *inst = contain    
 91                                                   
 92                                                   
 93                                                   
 94         INIT_WORK(&inst->free_work, crypto_des    
 95         schedule_work(&inst->free_work);          
 96 }                                                 
 97                                                   
 98 /*                                                
 99  * This function adds a spawn to the list seco    
100  * will be used at the end of crypto_remove_sp    
101  * instances, unless the spawn happens to be o    
102  * on by the new algorithm (nalg in crypto_rem    
103  *                                                
104  * This function is also responsible for resur    
105  * in the dependency chain of nalg by unsettin    
106  */                                               
107 static struct list_head *crypto_more_spawns(st    
108                                             st    
109                                             st    
110                                             st    
111 {                                                 
112         struct crypto_spawn *spawn, *n;           
113                                                   
114         spawn = list_first_entry_or_null(stack    
115         if (!spawn)                               
116                 return NULL;                      
117                                                   
118         n = list_prev_entry(spawn, list);         
119         list_move(&spawn->list, secondary_spaw    
120                                                   
121         if (list_is_last(&n->list, stack))        
122                 return top;                       
123                                                   
124         n = list_next_entry(n, list);             
125         if (!spawn->dead)                         
126                 n->dead = false;                  
127                                                   
128         return &n->inst->alg.cra_users;           
129 }                                                 
130                                                   
131 static void crypto_remove_instance(struct cryp    
132                                    struct list    
133 {                                                 
134         struct crypto_template *tmpl = inst->t    
135                                                   
136         if (crypto_is_dead(&inst->alg))           
137                 return;                           
138                                                   
139         inst->alg.cra_flags |= CRYPTO_ALG_DEAD    
140                                                   
141         if (!tmpl || !crypto_tmpl_get(tmpl))      
142                 return;                           
143                                                   
144         list_move(&inst->alg.cra_list, list);     
145         hlist_del(&inst->list);                   
146         inst->alg.cra_destroy = crypto_destroy    
147                                                   
148         BUG_ON(!list_empty(&inst->alg.cra_user    
149 }                                                 
150                                                   
151 /*                                                
152  * Given an algorithm alg, remove all algorith    
153  * through spawns.  If nalg is not null, then     
154  * that is depended on by nalg.  This is usefu    
155  * depends on alg.                                
156  */                                               
157 void crypto_remove_spawns(struct crypto_alg *a    
158                           struct crypto_alg *n    
159 {                                                 
160         u32 new_type = (nalg ?: alg)->cra_flag    
161         struct crypto_spawn *spawn, *n;           
162         LIST_HEAD(secondary_spawns);              
163         struct list_head *spawns;                 
164         LIST_HEAD(stack);                         
165         LIST_HEAD(top);                           
166                                                   
167         spawns = &alg->cra_users;                 
168         list_for_each_entry_safe(spawn, n, spa    
169                 if ((spawn->alg->cra_flags ^ n    
170                         continue;                 
171                                                   
172                 list_move(&spawn->list, &top);    
173         }                                         
174                                                   
175         /*                                        
176          * Perform a depth-first walk starting    
177          * the cra_users tree.  The list stack    
178          * from alg to the current spawn.         
179          */                                       
180         spawns = &top;                            
181         do {                                      
182                 while (!list_empty(spawns)) {     
183                         struct crypto_instance    
184                                                   
185                         spawn = list_first_ent    
186                                                   
187                         inst = spawn->inst;       
188                                                   
189                         list_move(&spawn->list    
190                         spawn->dead = !spawn->    
191                                                   
192                         if (!spawn->registered    
193                                 break;            
194                                                   
195                         BUG_ON(&inst->alg == a    
196                                                   
197                         if (&inst->alg == nalg    
198                                 break;            
199                                                   
200                         spawns = &inst->alg.cr    
201                                                   
202                         /*                        
203                          * Even if spawn->regi    
204                          * instance itself may    
205                          * This is because it     
206                          * registration.  Ther    
207                          * make the following     
208                          *                        
209                          * We may encounter an    
210                          * an instance's spawn    
211                          * being registered.      
212                          * NULL ->cra_users.ne    
213                          * properly initialize    
214                          * unregistered instan    
215                          * it the same as ->cr    
216                          */                       
217                         if (spawns->next == NU    
218                                 break;            
219                 }                                 
220         } while ((spawns = crypto_more_spawns(    
221                                                   
222                                                   
223         /*                                        
224          * Remove all instances that are marke    
225          * complete the resurrection of the ot    
226          * back to the cra_users list.            
227          */                                       
228         list_for_each_entry_safe(spawn, n, &se    
229                 if (!spawn->dead)                 
230                         list_move(&spawn->list    
231                 else if (spawn->registered)       
232                         crypto_remove_instance    
233         }                                         
234 }                                                 
235 EXPORT_SYMBOL_GPL(crypto_remove_spawns);          
236                                                   
237 static void crypto_alg_finish_registration(str    
238                                            boo    
239                                            str    
240 {                                                 
241         struct crypto_alg *q;                     
242                                                   
243         list_for_each_entry(q, &crypto_alg_lis    
244                 if (q == alg)                     
245                         continue;                 
246                                                   
247                 if (crypto_is_moribund(q))        
248                         continue;                 
249                                                   
250                 if (crypto_is_larval(q)) {        
251                         struct crypto_larval *    
252                                                   
253                         /*                        
254                          * Check to see if eit    
255                          * specific name can s    
256                          * by the larval entry    
257                          */                       
258                         if (strcmp(alg->cra_na    
259                             strcmp(alg->cra_dr    
260                                 continue;         
261                                                   
262                         if (larval->adult)        
263                                 continue;         
264                         if ((q->cra_flags ^ al    
265                                 continue;         
266                                                   
267                         if (fulfill_requests &    
268                                 larval->adult     
269                         else                      
270                                 larval->adult     
271                                                   
272                         continue;                 
273                 }                                 
274                                                   
275                 if (strcmp(alg->cra_name, q->c    
276                         continue;                 
277                                                   
278                 if (strcmp(alg->cra_driver_nam    
279                     q->cra_priority > alg->cra    
280                         continue;                 
281                                                   
282                 crypto_remove_spawns(q, algs_t    
283         }                                         
284                                                   
285         crypto_notify(CRYPTO_MSG_ALG_LOADED, a    
286 }                                                 
287                                                   
288 static struct crypto_larval *crypto_alloc_test    
289 {                                                 
290         struct crypto_larval *larval;             
291                                                   
292         if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER)    
293             IS_ENABLED(CONFIG_CRYPTO_MANAGER_D    
294             (alg->cra_flags & CRYPTO_ALG_INTER    
295                 return NULL; /* No self-test n    
296                                                   
297         larval = crypto_larval_alloc(alg->cra_    
298                                      alg->cra_    
299         if (IS_ERR(larval))                       
300                 return larval;                    
301                                                   
302         larval->adult = crypto_mod_get(alg);      
303         if (!larval->adult) {                     
304                 kfree(larval);                    
305                 return ERR_PTR(-ENOENT);          
306         }                                         
307                                                   
308         refcount_set(&larval->alg.cra_refcnt,     
309         memcpy(larval->alg.cra_driver_name, al    
310                CRYPTO_MAX_ALG_NAME);              
311         larval->alg.cra_priority = alg->cra_pr    
312                                                   
313         return larval;                            
314 }                                                 
315                                                   
316 static struct crypto_larval *                     
317 __crypto_register_alg(struct crypto_alg *alg,     
318 {                                                 
319         struct crypto_alg *q;                     
320         struct crypto_larval *larval;             
321         int ret = -EAGAIN;                        
322                                                   
323         if (crypto_is_dead(alg))                  
324                 goto err;                         
325                                                   
326         INIT_LIST_HEAD(&alg->cra_users);          
327                                                   
328         ret = -EEXIST;                            
329                                                   
330         list_for_each_entry(q, &crypto_alg_lis    
331                 if (q == alg)                     
332                         goto err;                 
333                                                   
334                 if (crypto_is_moribund(q))        
335                         continue;                 
336                                                   
337                 if (crypto_is_larval(q)) {        
338                         if (!strcmp(alg->cra_d    
339                                 goto err;         
340                         continue;                 
341                 }                                 
342                                                   
343                 if (!strcmp(q->cra_driver_name    
344                     !strcmp(q->cra_driver_name    
345                     !strcmp(q->cra_name, alg->    
346                         goto err;                 
347         }                                         
348                                                   
349         larval = crypto_alloc_test_larval(alg)    
350         if (IS_ERR(larval))                       
351                 goto out;                         
352                                                   
353         list_add(&alg->cra_list, &crypto_alg_l    
354                                                   
355         if (larval) {                             
356                 /* No cheating! */                
357                 alg->cra_flags &= ~CRYPTO_ALG_    
358                                                   
359                 list_add(&larval->alg.cra_list    
360         } else {                                  
361                 alg->cra_flags |= CRYPTO_ALG_T    
362                 crypto_alg_finish_registration    
363         }                                         
364                                                   
365 out:                                              
366         return larval;                            
367                                                   
368 err:                                              
369         larval = ERR_PTR(ret);                    
370         goto out;                                 
371 }                                                 
372                                                   
373 void crypto_alg_tested(const char *name, int e    
374 {                                                 
375         struct crypto_larval *test;               
376         struct crypto_alg *alg;                   
377         struct crypto_alg *q;                     
378         LIST_HEAD(list);                          
379         bool best;                                
380                                                   
381         down_write(&crypto_alg_sem);              
382         list_for_each_entry(q, &crypto_alg_lis    
383                 if (crypto_is_moribund(q) || !    
384                         continue;                 
385                                                   
386                 test = (struct crypto_larval *    
387                                                   
388                 if (!strcmp(q->cra_driver_name    
389                         goto found;               
390         }                                         
391                                                   
392         pr_err("alg: Unexpected test result fo    
393         goto unlock;                              
394                                                   
395 found:                                            
396         q->cra_flags |= CRYPTO_ALG_DEAD;          
397         alg = test->adult;                        
398                                                   
399         if (list_empty(&alg->cra_list))           
400                 goto complete;                    
401                                                   
402         if (err == -ECANCELED)                    
403                 alg->cra_flags |= CRYPTO_ALG_F    
404         else if (err)                             
405                 goto complete;                    
406         else                                      
407                 alg->cra_flags &= ~CRYPTO_ALG_    
408                                                   
409         alg->cra_flags |= CRYPTO_ALG_TESTED;      
410                                                   
411         /*                                        
412          * If a higher-priority implementation    
413          * currently being tested, then don't     
414          */                                       
415         best = true;                              
416         list_for_each_entry(q, &crypto_alg_lis    
417                 if (crypto_is_moribund(q) || !    
418                         continue;                 
419                                                   
420                 if (strcmp(alg->cra_name, q->c    
421                         continue;                 
422                                                   
423                 if (q->cra_priority > alg->cra    
424                         best = false;             
425                         break;                    
426                 }                                 
427         }                                         
428                                                   
429         crypto_alg_finish_registration(alg, be    
430                                                   
431 complete:                                         
432         complete_all(&test->completion);          
433                                                   
434 unlock:                                           
435         up_write(&crypto_alg_sem);                
436                                                   
437         crypto_remove_final(&list);               
438 }                                                 
439 EXPORT_SYMBOL_GPL(crypto_alg_tested);             
440                                                   
441 void crypto_remove_final(struct list_head *lis    
442 {                                                 
443         struct crypto_alg *alg;                   
444         struct crypto_alg *n;                     
445                                                   
446         list_for_each_entry_safe(alg, n, list,    
447                 list_del_init(&alg->cra_list);    
448                 crypto_alg_put(alg);              
449         }                                         
450 }                                                 
451 EXPORT_SYMBOL_GPL(crypto_remove_final);           
452                                                   
453 int crypto_register_alg(struct crypto_alg *alg    
454 {                                                 
455         struct crypto_larval *larval;             
456         LIST_HEAD(algs_to_put);                   
457         bool test_started = false;                
458         int err;                                  
459                                                   
460         alg->cra_flags &= ~CRYPTO_ALG_DEAD;       
461         err = crypto_check_alg(alg);              
462         if (err)                                  
463                 return err;                       
464                                                   
465         down_write(&crypto_alg_sem);              
466         larval = __crypto_register_alg(alg, &a    
467         if (!IS_ERR_OR_NULL(larval)) {            
468                 test_started = crypto_boot_tes    
469                 larval->test_started = test_st    
470         }                                         
471         up_write(&crypto_alg_sem);                
472                                                   
473         if (IS_ERR(larval))                       
474                 return PTR_ERR(larval);           
475         if (test_started)                         
476                 crypto_wait_for_test(larval);     
477         crypto_remove_final(&algs_to_put);        
478         return 0;                                 
479 }                                                 
480 EXPORT_SYMBOL_GPL(crypto_register_alg);           
481                                                   
482 static int crypto_remove_alg(struct crypto_alg    
483 {                                                 
484         if (unlikely(list_empty(&alg->cra_list    
485                 return -ENOENT;                   
486                                                   
487         alg->cra_flags |= CRYPTO_ALG_DEAD;        
488                                                   
489         list_del_init(&alg->cra_list);            
490         crypto_remove_spawns(alg, list, NULL);    
491                                                   
492         return 0;                                 
493 }                                                 
494                                                   
495 void crypto_unregister_alg(struct crypto_alg *    
496 {                                                 
497         int ret;                                  
498         LIST_HEAD(list);                          
499                                                   
500         down_write(&crypto_alg_sem);              
501         ret = crypto_remove_alg(alg, &list);      
502         up_write(&crypto_alg_sem);                
503                                                   
504         if (WARN(ret, "Algorithm %s is not reg    
505                 return;                           
506                                                   
507         if (WARN_ON(refcount_read(&alg->cra_re    
508                 return;                           
509                                                   
510         if (alg->cra_destroy)                     
511                 alg->cra_destroy(alg);            
512                                                   
513         crypto_remove_final(&list);               
514 }                                                 
515 EXPORT_SYMBOL_GPL(crypto_unregister_alg);         
516                                                   
517 int crypto_register_algs(struct crypto_alg *al    
518 {                                                 
519         int i, ret;                               
520                                                   
521         for (i = 0; i < count; i++) {             
522                 ret = crypto_register_alg(&alg    
523                 if (ret)                          
524                         goto err;                 
525         }                                         
526                                                   
527         return 0;                                 
528                                                   
529 err:                                              
530         for (--i; i >= 0; --i)                    
531                 crypto_unregister_alg(&algs[i]    
532                                                   
533         return ret;                               
534 }                                                 
535 EXPORT_SYMBOL_GPL(crypto_register_algs);          
536                                                   
537 void crypto_unregister_algs(struct crypto_alg     
538 {                                                 
539         int i;                                    
540                                                   
541         for (i = 0; i < count; i++)               
542                 crypto_unregister_alg(&algs[i]    
543 }                                                 
544 EXPORT_SYMBOL_GPL(crypto_unregister_algs);        
545                                                   
546 int crypto_register_template(struct crypto_tem    
547 {                                                 
548         struct crypto_template *q;                
549         int err = -EEXIST;                        
550                                                   
551         down_write(&crypto_alg_sem);              
552                                                   
553         crypto_check_module_sig(tmpl->module);    
554                                                   
555         list_for_each_entry(q, &crypto_templat    
556                 if (q == tmpl)                    
557                         goto out;                 
558         }                                         
559                                                   
560         list_add(&tmpl->list, &crypto_template    
561         err = 0;                                  
562 out:                                              
563         up_write(&crypto_alg_sem);                
564         return err;                               
565 }                                                 
566 EXPORT_SYMBOL_GPL(crypto_register_template);      
567                                                   
568 int crypto_register_templates(struct crypto_te    
569 {                                                 
570         int i, err;                               
571                                                   
572         for (i = 0; i < count; i++) {             
573                 err = crypto_register_template    
574                 if (err)                          
575                         goto out;                 
576         }                                         
577         return 0;                                 
578                                                   
579 out:                                              
580         for (--i; i >= 0; --i)                    
581                 crypto_unregister_template(&tm    
582         return err;                               
583 }                                                 
584 EXPORT_SYMBOL_GPL(crypto_register_templates);     
585                                                   
586 void crypto_unregister_template(struct crypto_    
587 {                                                 
588         struct crypto_instance *inst;             
589         struct hlist_node *n;                     
590         struct hlist_head *list;                  
591         LIST_HEAD(users);                         
592                                                   
593         down_write(&crypto_alg_sem);              
594                                                   
595         BUG_ON(list_empty(&tmpl->list));          
596         list_del_init(&tmpl->list);               
597                                                   
598         list = &tmpl->instances;                  
599         hlist_for_each_entry(inst, list, list)    
600                 int err = crypto_remove_alg(&i    
601                                                   
602                 BUG_ON(err);                      
603         }                                         
604                                                   
605         up_write(&crypto_alg_sem);                
606                                                   
607         hlist_for_each_entry_safe(inst, n, lis    
608                 BUG_ON(refcount_read(&inst->al    
609                 crypto_free_instance(inst);       
610         }                                         
611         crypto_remove_final(&users);              
612 }                                                 
613 EXPORT_SYMBOL_GPL(crypto_unregister_template);    
614                                                   
615 void crypto_unregister_templates(struct crypto    
616 {                                                 
617         int i;                                    
618                                                   
619         for (i = count - 1; i >= 0; --i)          
620                 crypto_unregister_template(&tm    
621 }                                                 
622 EXPORT_SYMBOL_GPL(crypto_unregister_templates)    
623                                                   
624 static struct crypto_template *__crypto_lookup    
625 {                                                 
626         struct crypto_template *q, *tmpl = NUL    
627                                                   
628         down_read(&crypto_alg_sem);               
629         list_for_each_entry(q, &crypto_templat    
630                 if (strcmp(q->name, name))        
631                         continue;                 
632                 if (unlikely(!crypto_tmpl_get(    
633                         continue;                 
634                                                   
635                 tmpl = q;                         
636                 break;                            
637         }                                         
638         up_read(&crypto_alg_sem);                 
639                                                   
640         return tmpl;                              
641 }                                                 
642                                                   
643 struct crypto_template *crypto_lookup_template    
644 {                                                 
645         return try_then_request_module(__crypt    
646                                        "crypto    
647 }                                                 
648 EXPORT_SYMBOL_GPL(crypto_lookup_template);        
649                                                   
650 int crypto_register_instance(struct crypto_tem    
651                              struct crypto_ins    
652 {                                                 
653         struct crypto_larval *larval;             
654         struct crypto_spawn *spawn;               
655         u32 fips_internal = 0;                    
656         LIST_HEAD(algs_to_put);                   
657         int err;                                  
658                                                   
659         err = crypto_check_alg(&inst->alg);       
660         if (err)                                  
661                 return err;                       
662                                                   
663         inst->alg.cra_module = tmpl->module;      
664         inst->alg.cra_flags |= CRYPTO_ALG_INST    
665                                                   
666         down_write(&crypto_alg_sem);              
667                                                   
668         larval = ERR_PTR(-EAGAIN);                
669         for (spawn = inst->spawns; spawn;) {      
670                 struct crypto_spawn *next;        
671                                                   
672                 if (spawn->dead)                  
673                         goto unlock;              
674                                                   
675                 next = spawn->next;               
676                 spawn->inst = inst;               
677                 spawn->registered = true;         
678                                                   
679                 fips_internal |= spawn->alg->c    
680                                                   
681                 crypto_mod_put(spawn->alg);       
682                                                   
683                 spawn = next;                     
684         }                                         
685                                                   
686         inst->alg.cra_flags |= (fips_internal     
687                                                   
688         larval = __crypto_register_alg(&inst->    
689         if (IS_ERR(larval))                       
690                 goto unlock;                      
691         else if (larval)                          
692                 larval->test_started = true;      
693                                                   
694         hlist_add_head(&inst->list, &tmpl->ins    
695         inst->tmpl = tmpl;                        
696                                                   
697 unlock:                                           
698         up_write(&crypto_alg_sem);                
699                                                   
700         if (IS_ERR(larval))                       
701                 return PTR_ERR(larval);           
702         if (larval)                               
703                 crypto_wait_for_test(larval);     
704         crypto_remove_final(&algs_to_put);        
705         return 0;                                 
706 }                                                 
707 EXPORT_SYMBOL_GPL(crypto_register_instance);      
708                                                   
709 void crypto_unregister_instance(struct crypto_    
710 {                                                 
711         LIST_HEAD(list);                          
712                                                   
713         down_write(&crypto_alg_sem);              
714                                                   
715         crypto_remove_spawns(&inst->alg, &list    
716         crypto_remove_instance(inst, &list);      
717                                                   
718         up_write(&crypto_alg_sem);                
719                                                   
720         crypto_remove_final(&list);               
721 }                                                 
722 EXPORT_SYMBOL_GPL(crypto_unregister_instance);    
723                                                   
724 int crypto_grab_spawn(struct crypto_spawn *spa    
725                       const char *name, u32 ty    
726 {                                                 
727         struct crypto_alg *alg;                   
728         int err = -EAGAIN;                        
729                                                   
730         if (WARN_ON_ONCE(inst == NULL))           
731                 return -EINVAL;                   
732                                                   
733         /* Allow the result of crypto_attr_alg    
734         if (IS_ERR(name))                         
735                 return PTR_ERR(name);             
736                                                   
737         alg = crypto_find_alg(name, spawn->fro    
738                               type | CRYPTO_AL    
739         if (IS_ERR(alg))                          
740                 return PTR_ERR(alg);              
741                                                   
742         down_write(&crypto_alg_sem);              
743         if (!crypto_is_moribund(alg)) {           
744                 list_add(&spawn->list, &alg->c    
745                 spawn->alg = alg;                 
746                 spawn->mask = mask;               
747                 spawn->next = inst->spawns;       
748                 inst->spawns = spawn;             
749                 inst->alg.cra_flags |=            
750                         (alg->cra_flags & CRYP    
751                 err = 0;                          
752         }                                         
753         up_write(&crypto_alg_sem);                
754         if (err)                                  
755                 crypto_mod_put(alg);              
756         return err;                               
757 }                                                 
758 EXPORT_SYMBOL_GPL(crypto_grab_spawn);             
759                                                   
760 void crypto_drop_spawn(struct crypto_spawn *sp    
761 {                                                 
762         if (!spawn->alg) /* not yet initialize    
763                 return;                           
764                                                   
765         down_write(&crypto_alg_sem);              
766         if (!spawn->dead)                         
767                 list_del(&spawn->list);           
768         up_write(&crypto_alg_sem);                
769                                                   
770         if (!spawn->registered)                   
771                 crypto_mod_put(spawn->alg);       
772 }                                                 
773 EXPORT_SYMBOL_GPL(crypto_drop_spawn);             
774                                                   
775 static struct crypto_alg *crypto_spawn_alg(str    
776 {                                                 
777         struct crypto_alg *alg = ERR_PTR(-EAGA    
778         struct crypto_alg *target;                
779         bool shoot = false;                       
780                                                   
781         down_read(&crypto_alg_sem);               
782         if (!spawn->dead) {                       
783                 alg = spawn->alg;                 
784                 if (!crypto_mod_get(alg)) {       
785                         target = crypto_alg_ge    
786                         shoot = true;             
787                         alg = ERR_PTR(-EAGAIN)    
788                 }                                 
789         }                                         
790         up_read(&crypto_alg_sem);                 
791                                                   
792         if (shoot) {                              
793                 crypto_shoot_alg(target);         
794                 crypto_alg_put(target);           
795         }                                         
796                                                   
797         return alg;                               
798 }                                                 
799                                                   
800 struct crypto_tfm *crypto_spawn_tfm(struct cry    
801                                     u32 mask)     
802 {                                                 
803         struct crypto_alg *alg;                   
804         struct crypto_tfm *tfm;                   
805                                                   
806         alg = crypto_spawn_alg(spawn);            
807         if (IS_ERR(alg))                          
808                 return ERR_CAST(alg);             
809                                                   
810         tfm = ERR_PTR(-EINVAL);                   
811         if (unlikely((alg->cra_flags ^ type) &    
812                 goto out_put_alg;                 
813                                                   
814         tfm = __crypto_alloc_tfm(alg, type, ma    
815         if (IS_ERR(tfm))                          
816                 goto out_put_alg;                 
817                                                   
818         return tfm;                               
819                                                   
820 out_put_alg:                                      
821         crypto_mod_put(alg);                      
822         return tfm;                               
823 }                                                 
824 EXPORT_SYMBOL_GPL(crypto_spawn_tfm);              
825                                                   
826 void *crypto_spawn_tfm2(struct crypto_spawn *s    
827 {                                                 
828         struct crypto_alg *alg;                   
829         struct crypto_tfm *tfm;                   
830                                                   
831         alg = crypto_spawn_alg(spawn);            
832         if (IS_ERR(alg))                          
833                 return ERR_CAST(alg);             
834                                                   
835         tfm = crypto_create_tfm(alg, spawn->fr    
836         if (IS_ERR(tfm))                          
837                 goto out_put_alg;                 
838                                                   
839         return tfm;                               
840                                                   
841 out_put_alg:                                      
842         crypto_mod_put(alg);                      
843         return tfm;                               
844 }                                                 
845 EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);             
846                                                   
847 int crypto_register_notifier(struct notifier_b    
848 {                                                 
849         return blocking_notifier_chain_registe    
850 }                                                 
851 EXPORT_SYMBOL_GPL(crypto_register_notifier);      
852                                                   
853 int crypto_unregister_notifier(struct notifier    
854 {                                                 
855         return blocking_notifier_chain_unregis    
856 }                                                 
857 EXPORT_SYMBOL_GPL(crypto_unregister_notifier);    
858                                                   
859 struct crypto_attr_type *crypto_get_attr_type(    
860 {                                                 
861         struct rtattr *rta = tb[0];               
862         struct crypto_attr_type *algt;            
863                                                   
864         if (!rta)                                 
865                 return ERR_PTR(-ENOENT);          
866         if (RTA_PAYLOAD(rta) < sizeof(*algt))     
867                 return ERR_PTR(-EINVAL);          
868         if (rta->rta_type != CRYPTOA_TYPE)        
869                 return ERR_PTR(-EINVAL);          
870                                                   
871         algt = RTA_DATA(rta);                     
872                                                   
873         return algt;                              
874 }                                                 
875 EXPORT_SYMBOL_GPL(crypto_get_attr_type);          
876                                                   
877 /**                                               
878  * crypto_check_attr_type() - check algorithm     
879  * @tb: the template parameters                   
880  * @type: the algorithm type the template woul    
881  * @mask_ret: (output) the mask that should be    
882  *            to restrict the flags of any inn    
883  *                                                
884  * Validate that the algorithm type the user r    
885  * one the template would actually be instanti    
886  * doing crypto_alloc_shash("cbc(aes)", ...),     
887  * the "cbc" template creates an "skcipher" al    
888  *                                                
889  * Also compute the mask to use to restrict th    
890  *                                                
891  * Return: 0 on success; -errno on failure        
892  */                                               
893 int crypto_check_attr_type(struct rtattr **tb,    
894 {                                                 
895         struct crypto_attr_type *algt;            
896                                                   
897         algt = crypto_get_attr_type(tb);          
898         if (IS_ERR(algt))                         
899                 return PTR_ERR(algt);             
900                                                   
901         if ((algt->type ^ type) & algt->mask)     
902                 return -EINVAL;                   
903                                                   
904         *mask_ret = crypto_algt_inherited_mask    
905         return 0;                                 
906 }                                                 
907 EXPORT_SYMBOL_GPL(crypto_check_attr_type);        
908                                                   
909 const char *crypto_attr_alg_name(struct rtattr    
910 {                                                 
911         struct crypto_attr_alg *alga;             
912                                                   
913         if (!rta)                                 
914                 return ERR_PTR(-ENOENT);          
915         if (RTA_PAYLOAD(rta) < sizeof(*alga))     
916                 return ERR_PTR(-EINVAL);          
917         if (rta->rta_type != CRYPTOA_ALG)         
918                 return ERR_PTR(-EINVAL);          
919                                                   
920         alga = RTA_DATA(rta);                     
921         alga->name[CRYPTO_MAX_ALG_NAME - 1] =     
922                                                   
923         return alga->name;                        
924 }                                                 
925 EXPORT_SYMBOL_GPL(crypto_attr_alg_name);          
926                                                   
927 int crypto_inst_setname(struct crypto_instance    
928                         struct crypto_alg *alg    
929 {                                                 
930         if (snprintf(inst->alg.cra_name, CRYPT    
931                      alg->cra_name) >= CRYPTO_    
932                 return -ENAMETOOLONG;             
933                                                   
934         if (snprintf(inst->alg.cra_driver_name    
935                      name, alg->cra_driver_nam    
936                 return -ENAMETOOLONG;             
937                                                   
938         return 0;                                 
939 }                                                 
940 EXPORT_SYMBOL_GPL(crypto_inst_setname);           
941                                                   
942 void crypto_init_queue(struct crypto_queue *qu    
943 {                                                 
944         INIT_LIST_HEAD(&queue->list);             
945         queue->backlog = &queue->list;            
946         queue->qlen = 0;                          
947         queue->max_qlen = max_qlen;               
948 }                                                 
949 EXPORT_SYMBOL_GPL(crypto_init_queue);             
950                                                   
951 int crypto_enqueue_request(struct crypto_queue    
952                            struct crypto_async    
953 {                                                 
954         int err = -EINPROGRESS;                   
955                                                   
956         if (unlikely(queue->qlen >= queue->max    
957                 if (!(request->flags & CRYPTO_    
958                         err = -ENOSPC;            
959                         goto out;                 
960                 }                                 
961                 err = -EBUSY;                     
962                 if (queue->backlog == &queue->    
963                         queue->backlog = &requ    
964         }                                         
965                                                   
966         queue->qlen++;                            
967         list_add_tail(&request->list, &queue->    
968                                                   
969 out:                                              
970         return err;                               
971 }                                                 
972 EXPORT_SYMBOL_GPL(crypto_enqueue_request);        
973                                                   
974 void crypto_enqueue_request_head(struct crypto    
975                                  struct crypto    
976 {                                                 
977         if (unlikely(queue->qlen >= queue->max    
978                 queue->backlog = queue->backlo    
979                                                   
980         queue->qlen++;                            
981         list_add(&request->list, &queue->list)    
982 }                                                 
983 EXPORT_SYMBOL_GPL(crypto_enqueue_request_head)    
984                                                   
985 struct crypto_async_request *crypto_dequeue_re    
986 {                                                 
987         struct list_head *request;                
988                                                   
989         if (unlikely(!queue->qlen))               
990                 return NULL;                      
991                                                   
992         queue->qlen--;                            
993                                                   
994         if (queue->backlog != &queue->list)       
995                 queue->backlog = queue->backlo    
996                                                   
997         request = queue->list.next;               
998         list_del(request);                        
999                                                   
1000         return list_entry(request, struct cry    
1001 }                                                
1002 EXPORT_SYMBOL_GPL(crypto_dequeue_request);       
1003                                                  
1004 static inline void crypto_inc_byte(u8 *a, uns    
1005 {                                                
1006         u8 *b = (a + size);                      
1007         u8 c;                                    
1008                                                  
1009         for (; size; size--) {                   
1010                 c = *--b + 1;                    
1011                 *b = c;                          
1012                 if (c)                           
1013                         break;                   
1014         }                                        
1015 }                                                
1016                                                  
1017 void crypto_inc(u8 *a, unsigned int size)        
1018 {                                                
1019         __be32 *b = (__be32 *)(a + size);        
1020         u32 c;                                   
1021                                                  
1022         if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_    
1023             IS_ALIGNED((unsigned long)b, __al    
1024                 for (; size >= 4; size -= 4)     
1025                         c = be32_to_cpu(*--b)    
1026                         *b = cpu_to_be32(c);     
1027                         if (likely(c))           
1028                                 return;          
1029                 }                                
1030                                                  
1031         crypto_inc_byte(a, size);                
1032 }                                                
1033 EXPORT_SYMBOL_GPL(crypto_inc);                   
1034                                                  
1035 unsigned int crypto_alg_extsize(struct crypto    
1036 {                                                
1037         return alg->cra_ctxsize +                
1038                (alg->cra_alignmask & ~(crypto    
1039 }                                                
1040 EXPORT_SYMBOL_GPL(crypto_alg_extsize);           
1041                                                  
1042 int crypto_type_has_alg(const char *name, con    
1043                         u32 type, u32 mask)      
1044 {                                                
1045         int ret = 0;                             
1046         struct crypto_alg *alg = crypto_find_    
1047                                                  
1048         if (!IS_ERR(alg)) {                      
1049                 crypto_mod_put(alg);             
1050                 ret = 1;                         
1051         }                                        
1052                                                  
1053         return ret;                              
1054 }                                                
1055 EXPORT_SYMBOL_GPL(crypto_type_has_alg);          
1056                                                  
1057 static void __init crypto_start_tests(void)      
1058 {                                                
1059         if (!IS_BUILTIN(CONFIG_CRYPTO_ALGAPI)    
1060                 return;                          
1061                                                  
1062         if (IS_ENABLED(CONFIG_CRYPTO_MANAGER_    
1063                 return;                          
1064                                                  
1065         for (;;) {                               
1066                 struct crypto_larval *larval     
1067                 struct crypto_alg *q;            
1068                                                  
1069                 down_write(&crypto_alg_sem);     
1070                                                  
1071                 list_for_each_entry(q, &crypt    
1072                         struct crypto_larval     
1073                                                  
1074                         if (!crypto_is_larval    
1075                                 continue;        
1076                                                  
1077                         l = (void *)q;           
1078                                                  
1079                         if (!crypto_is_test_l    
1080                                 continue;        
1081                                                  
1082                         if (l->test_started)     
1083                                 continue;        
1084                                                  
1085                         l->test_started = tru    
1086                         larval = l;              
1087                         break;                   
1088                 }                                
1089                                                  
1090                 up_write(&crypto_alg_sem);       
1091                                                  
1092                 if (!larval)                     
1093                         break;                   
1094                                                  
1095                 crypto_wait_for_test(larval);    
1096         }                                        
1097                                                  
1098         set_crypto_boot_test_finished();         
1099 }                                                
1100                                                  
1101 static int __init crypto_algapi_init(void)       
1102 {                                                
1103         crypto_init_proc();                      
1104         crypto_start_tests();                    
1105         return 0;                                
1106 }                                                
1107                                                  
1108 static void __exit crypto_algapi_exit(void)      
1109 {                                                
1110         crypto_exit_proc();                      
1111 }                                                
1112                                                  
1113 /*                                               
1114  * We run this at late_initcall so that all t    
1115  * have had a chance to register themselves f    
1116  */                                              
1117 late_initcall(crypto_algapi_init);               
1118 module_exit(crypto_algapi_exit);                 
1119                                                  
1120 MODULE_LICENSE("GPL");                           
1121 MODULE_DESCRIPTION("Cryptographic algorithms     
1122 MODULE_SOFTDEP("pre: cryptomgr");                
1123                                                  

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