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

TOMOYO Linux Cross Reference
Linux/crypto/rsa.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/rsa.c (Version linux-6.12-rc7) and /crypto/rsa.c (Version linux-5.15.169)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /* RSA asymmetric public-key algorithm [RFC344    
  3  *                                                
  4  * Copyright (c) 2015, Intel Corporation          
  5  * Authors: Tadeusz Struk <tadeusz.struk@intel    
  6  */                                               
  7                                                   
  8 #include <linux/fips.h>                           
  9 #include <linux/module.h>                         
 10 #include <linux/mpi.h>                            
 11 #include <crypto/internal/rsa.h>                  
 12 #include <crypto/internal/akcipher.h>             
 13 #include <crypto/akcipher.h>                      
 14 #include <crypto/algapi.h>                        
 15                                                   
 16 struct rsa_mpi_key {                              
 17         MPI n;                                    
 18         MPI e;                                    
 19         MPI d;                                    
 20         MPI p;                                    
 21         MPI q;                                    
 22         MPI dp;                                   
 23         MPI dq;                                   
 24         MPI qinv;                                 
 25 };                                                
 26                                                   
 27 static int rsa_check_payload(MPI x, MPI n)        
 28 {                                                 
 29         MPI n1;                                   
 30                                                   
 31         if (mpi_cmp_ui(x, 1) <= 0)                
 32                 return -EINVAL;                   
 33                                                   
 34         n1 = mpi_alloc(0);                        
 35         if (!n1)                                  
 36                 return -ENOMEM;                   
 37                                                   
 38         if (mpi_sub_ui(n1, n, 1) || mpi_cmp(x,    
 39                 mpi_free(n1);                     
 40                 return -EINVAL;                   
 41         }                                         
 42                                                   
 43         mpi_free(n1);                             
 44         return 0;                                 
 45 }                                                 
 46                                                   
 47 /*                                                
 48  * RSAEP function [RFC3447 sec 5.1.1]             
 49  * c = m^e mod n;                                 
 50  */                                               
 51 static int _rsa_enc(const struct rsa_mpi_key *    
 52 {                                                 
 53         /*                                        
 54          * Even though (1) in RFC3447 only req    
 55          * slightly more conservative and requ    
 56          * with SP 800-56Br2, Section 7.1.1.      
 57          */                                       
 58         if (rsa_check_payload(m, key->n))         
 59                 return -EINVAL;                   
 60                                                   
 61         /* (2) c = m^e mod n */                   
 62         return mpi_powm(c, m, key->e, key->n);    
 63 }                                                 
 64                                                   
 65 /*                                                
 66  * RSADP function [RFC3447 sec 5.1.2]             
 67  * m_1 = c^dP mod p;                              
 68  * m_2 = c^dQ mod q;                              
 69  * h = (m_1 - m_2) * qInv mod p;                  
 70  * m = m_2 + q * h;                               
 71  */                                               
 72 static int _rsa_dec_crt(const struct rsa_mpi_k    
 73 {                                                 
 74         MPI m2, m12_or_qh;                        
 75         int ret = -ENOMEM;                        
 76                                                   
 77         /*                                        
 78          * Even though (1) in RFC3447 only req    
 79          * slightly more conservative and requ    
 80          * with SP 800-56Br2, Section 7.1.2.      
 81          */                                       
 82         if (rsa_check_payload(c, key->n))         
 83                 return -EINVAL;                   
 84                                                   
 85         m2 = mpi_alloc(0);                        
 86         m12_or_qh = mpi_alloc(0);                 
 87         if (!m2 || !m12_or_qh)                    
 88                 goto err_free_mpi;                
 89                                                   
 90         /* (2i) m_1 = c^dP mod p */               
 91         ret = mpi_powm(m_or_m1_or_h, c, key->d    
 92         if (ret)                                  
 93                 goto err_free_mpi;                
 94                                                   
 95         /* (2i) m_2 = c^dQ mod q */               
 96         ret = mpi_powm(m2, c, key->dq, key->q)    
 97         if (ret)                                  
 98                 goto err_free_mpi;                
 99                                                   
100         /* (2iii) h = (m_1 - m_2) * qInv mod p    
101         ret = mpi_sub(m12_or_qh, m_or_m1_or_h,    
102               mpi_mulm(m_or_m1_or_h, m12_or_qh    
103                                                   
104         /* (2iv) m = m_2 + q * h */               
105         ret = ret ?:                              
106               mpi_mul(m12_or_qh, key->q, m_or_    
107               mpi_addm(m_or_m1_or_h, m2, m12_o    
108                                                   
109 err_free_mpi:                                     
110         mpi_free(m12_or_qh);                      
111         mpi_free(m2);                             
112         return ret;                               
113 }                                                 
114                                                   
115 static inline struct rsa_mpi_key *rsa_get_key(    
116 {                                                 
117         return akcipher_tfm_ctx(tfm);             
118 }                                                 
119                                                   
120 static int rsa_enc(struct akcipher_request *re    
121 {                                                 
122         struct crypto_akcipher *tfm = crypto_a    
123         const struct rsa_mpi_key *pkey = rsa_g    
124         MPI m, c = mpi_alloc(0);                  
125         int ret = 0;                              
126         int sign;                                 
127                                                   
128         if (!c)                                   
129                 return -ENOMEM;                   
130                                                   
131         if (unlikely(!pkey->n || !pkey->e)) {     
132                 ret = -EINVAL;                    
133                 goto err_free_c;                  
134         }                                         
135                                                   
136         ret = -ENOMEM;                            
137         m = mpi_read_raw_from_sgl(req->src, re    
138         if (!m)                                   
139                 goto err_free_c;                  
140                                                   
141         ret = _rsa_enc(pkey, c, m);               
142         if (ret)                                  
143                 goto err_free_m;                  
144                                                   
145         ret = mpi_write_to_sgl(c, req->dst, re    
146         if (ret)                                  
147                 goto err_free_m;                  
148                                                   
149         if (sign < 0)                             
150                 ret = -EBADMSG;                   
151                                                   
152 err_free_m:                                       
153         mpi_free(m);                              
154 err_free_c:                                       
155         mpi_free(c);                              
156         return ret;                               
157 }                                                 
158                                                   
159 static int rsa_dec(struct akcipher_request *re    
160 {                                                 
161         struct crypto_akcipher *tfm = crypto_a    
162         const struct rsa_mpi_key *pkey = rsa_g    
163         MPI c, m = mpi_alloc(0);                  
164         int ret = 0;                              
165         int sign;                                 
166                                                   
167         if (!m)                                   
168                 return -ENOMEM;                   
169                                                   
170         if (unlikely(!pkey->n || !pkey->d)) {     
171                 ret = -EINVAL;                    
172                 goto err_free_m;                  
173         }                                         
174                                                   
175         ret = -ENOMEM;                            
176         c = mpi_read_raw_from_sgl(req->src, re    
177         if (!c)                                   
178                 goto err_free_m;                  
179                                                   
180         ret = _rsa_dec_crt(pkey, m, c);           
181         if (ret)                                  
182                 goto err_free_c;                  
183                                                   
184         ret = mpi_write_to_sgl(m, req->dst, re    
185         if (ret)                                  
186                 goto err_free_c;                  
187                                                   
188         if (sign < 0)                             
189                 ret = -EBADMSG;                   
190 err_free_c:                                       
191         mpi_free(c);                              
192 err_free_m:                                       
193         mpi_free(m);                              
194         return ret;                               
195 }                                                 
196                                                   
197 static void rsa_free_mpi_key(struct rsa_mpi_ke    
198 {                                                 
199         mpi_free(key->d);                         
200         mpi_free(key->e);                         
201         mpi_free(key->n);                         
202         mpi_free(key->p);                         
203         mpi_free(key->q);                         
204         mpi_free(key->dp);                        
205         mpi_free(key->dq);                        
206         mpi_free(key->qinv);                      
207         key->d = NULL;                            
208         key->e = NULL;                            
209         key->n = NULL;                            
210         key->p = NULL;                            
211         key->q = NULL;                            
212         key->dp = NULL;                           
213         key->dq = NULL;                           
214         key->qinv = NULL;                         
215 }                                                 
216                                                   
217 static int rsa_check_key_length(unsigned int l    
218 {                                                 
219         switch (len) {                            
220         case 512:                                 
221         case 1024:                                
222         case 1536:                                
223                 if (fips_enabled)                 
224                         return -EINVAL;           
225                 fallthrough;                      
226         case 2048:                                
227         case 3072:                                
228         case 4096:                                
229                 return 0;                         
230         }                                         
231                                                   
232         return -EINVAL;                           
233 }                                                 
234                                                   
235 static int rsa_check_exponent_fips(MPI e)         
236 {                                                 
237         MPI e_max = NULL;                         
238         int err;                                  
239                                                   
240         /* check if odd */                        
241         if (!mpi_test_bit(e, 0)) {                
242                 return -EINVAL;                   
243         }                                         
244                                                   
245         /* check if 2^16 < e < 2^256. */          
246         if (mpi_cmp_ui(e, 65536) <= 0) {          
247                 return -EINVAL;                   
248         }                                         
249                                                   
250         e_max = mpi_alloc(0);                     
251         if (!e_max)                               
252                 return -ENOMEM;                   
253                                                   
254         err = mpi_set_bit(e_max, 256);            
255         if (err) {                                
256                 mpi_free(e_max);                  
257                 return err;                       
258         }                                         
259                                                   
260         if (mpi_cmp(e, e_max) >= 0) {             
261                 mpi_free(e_max);                  
262                 return -EINVAL;                   
263         }                                         
264                                                   
265         mpi_free(e_max);                          
266         return 0;                                 
267 }                                                 
268                                                   
269 static int rsa_set_pub_key(struct crypto_akcip    
270                            unsigned int keylen    
271 {                                                 
272         struct rsa_mpi_key *mpi_key = akcipher    
273         struct rsa_key raw_key = {0};             
274         int ret;                                  
275                                                   
276         /* Free the old MPI key if any */         
277         rsa_free_mpi_key(mpi_key);                
278                                                   
279         ret = rsa_parse_pub_key(&raw_key, key,    
280         if (ret)                                  
281                 return ret;                       
282                                                   
283         mpi_key->e = mpi_read_raw_data(raw_key    
284         if (!mpi_key->e)                          
285                 goto err;                         
286                                                   
287         mpi_key->n = mpi_read_raw_data(raw_key    
288         if (!mpi_key->n)                          
289                 goto err;                         
290                                                   
291         if (rsa_check_key_length(mpi_get_size(    
292                 rsa_free_mpi_key(mpi_key);        
293                 return -EINVAL;                   
294         }                                         
295                                                   
296         if (fips_enabled && rsa_check_exponent    
297                 rsa_free_mpi_key(mpi_key);        
298                 return -EINVAL;                   
299         }                                         
300                                                   
301         return 0;                                 
302                                                   
303 err:                                              
304         rsa_free_mpi_key(mpi_key);                
305         return -ENOMEM;                           
306 }                                                 
307                                                   
308 static int rsa_set_priv_key(struct crypto_akci    
309                             unsigned int keyle    
310 {                                                 
311         struct rsa_mpi_key *mpi_key = akcipher    
312         struct rsa_key raw_key = {0};             
313         int ret;                                  
314                                                   
315         /* Free the old MPI key if any */         
316         rsa_free_mpi_key(mpi_key);                
317                                                   
318         ret = rsa_parse_priv_key(&raw_key, key    
319         if (ret)                                  
320                 return ret;                       
321                                                   
322         mpi_key->d = mpi_read_raw_data(raw_key    
323         if (!mpi_key->d)                          
324                 goto err;                         
325                                                   
326         mpi_key->e = mpi_read_raw_data(raw_key    
327         if (!mpi_key->e)                          
328                 goto err;                         
329                                                   
330         mpi_key->n = mpi_read_raw_data(raw_key    
331         if (!mpi_key->n)                          
332                 goto err;                         
333                                                   
334         mpi_key->p = mpi_read_raw_data(raw_key    
335         if (!mpi_key->p)                          
336                 goto err;                         
337                                                   
338         mpi_key->q = mpi_read_raw_data(raw_key    
339         if (!mpi_key->q)                          
340                 goto err;                         
341                                                   
342         mpi_key->dp = mpi_read_raw_data(raw_ke    
343         if (!mpi_key->dp)                         
344                 goto err;                         
345                                                   
346         mpi_key->dq = mpi_read_raw_data(raw_ke    
347         if (!mpi_key->dq)                         
348                 goto err;                         
349                                                   
350         mpi_key->qinv = mpi_read_raw_data(raw_    
351         if (!mpi_key->qinv)                       
352                 goto err;                         
353                                                   
354         if (rsa_check_key_length(mpi_get_size(    
355                 rsa_free_mpi_key(mpi_key);        
356                 return -EINVAL;                   
357         }                                         
358                                                   
359         if (fips_enabled && rsa_check_exponent    
360                 rsa_free_mpi_key(mpi_key);        
361                 return -EINVAL;                   
362         }                                         
363                                                   
364         return 0;                                 
365                                                   
366 err:                                              
367         rsa_free_mpi_key(mpi_key);                
368         return -ENOMEM;                           
369 }                                                 
370                                                   
371 static unsigned int rsa_max_size(struct crypto    
372 {                                                 
373         struct rsa_mpi_key *pkey = akcipher_tf    
374                                                   
375         return mpi_get_size(pkey->n);             
376 }                                                 
377                                                   
378 static void rsa_exit_tfm(struct crypto_akciphe    
379 {                                                 
380         struct rsa_mpi_key *pkey = akcipher_tf    
381                                                   
382         rsa_free_mpi_key(pkey);                   
383 }                                                 
384                                                   
385 static struct akcipher_alg rsa = {                
386         .encrypt = rsa_enc,                       
387         .decrypt = rsa_dec,                       
388         .set_priv_key = rsa_set_priv_key,         
389         .set_pub_key = rsa_set_pub_key,           
390         .max_size = rsa_max_size,                 
391         .exit = rsa_exit_tfm,                     
392         .base = {                                 
393                 .cra_name = "rsa",                
394                 .cra_driver_name = "rsa-generi    
395                 .cra_priority = 100,              
396                 .cra_module = THIS_MODULE,        
397                 .cra_ctxsize = sizeof(struct r    
398         },                                        
399 };                                                
400                                                   
401 static int __init rsa_init(void)                  
402 {                                                 
403         int err;                                  
404                                                   
405         err = crypto_register_akcipher(&rsa);     
406         if (err)                                  
407                 return err;                       
408                                                   
409         err = crypto_register_template(&rsa_pk    
410         if (err) {                                
411                 crypto_unregister_akcipher(&rs    
412                 return err;                       
413         }                                         
414                                                   
415         return 0;                                 
416 }                                                 
417                                                   
418 static void __exit rsa_exit(void)                 
419 {                                                 
420         crypto_unregister_template(&rsa_pkcs1p    
421         crypto_unregister_akcipher(&rsa);         
422 }                                                 
423                                                   
424 subsys_initcall(rsa_init);                        
425 module_exit(rsa_exit);                            
426 MODULE_ALIAS_CRYPTO("rsa");                       
427 MODULE_LICENSE("GPL");                            
428 MODULE_DESCRIPTION("RSA generic algorithm");      
429                                                   

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