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

TOMOYO Linux Cross Reference
Linux/crypto/keywrap.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/keywrap.c (Version linux-6.11.5) and /crypto/keywrap.c (Version linux-2.6.32.71)


  1 /*                                                  1 
  2  * Key Wrapping: RFC3394 / NIST SP800-38F         
  3  *                                                
  4  * Copyright (C) 2015, Stephan Mueller <smuell    
  5  *                                                
  6  * Redistribution and use in source and binary    
  7  * modification, are permitted provided that t    
  8  * are met:                                       
  9  * 1. Redistributions of source code must reta    
 10  *    notice, and the entire permission notice    
 11  *    including the disclaimer of warranties.     
 12  * 2. Redistributions in binary form must repr    
 13  *    notice, this list of conditions and the     
 14  *    documentation and/or other materials pro    
 15  * 3. The name of the author may not be used t    
 16  *    products derived from this software with    
 17  *    written permission.                         
 18  *                                                
 19  * ALTERNATIVELY, this product may be distribu    
 20  * the GNU General Public License, in which ca    
 21  * are required INSTEAD OF the above restricti    
 22  * necessary due to a potential bad interactio    
 23  * the restrictions contained in a BSD-style c    
 24  *                                                
 25  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY    
 26  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO,     
 27  * OF MERCHANTABILITY AND FITNESS FOR A PARTIC    
 28  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT S    
 29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL    
 30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT L    
 31  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US    
 32  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND O    
 33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIAB    
 34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING    
 35  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED O    
 36  * DAMAGE.                                        
 37  */                                               
 38                                                   
 39 /*                                                
 40  * Note for using key wrapping:                   
 41  *                                                
 42  *      * The result of the encryption operati    
 43  *        with the 2nd semiblock. The first se    
 44  *        The IV used to start the encryption     
 45  *                                                
 46  *      * The input for the decryption is the     
 47  *        IV. The ciphertext is the data start    
 48  *        return code of the decryption operat    
 49  *        integrity error occurs.                 
 50  *                                                
 51  * To obtain the full result of an encryption     
 52  * caller must allocate a buffer of plaintext     
 53  *                                                
 54  *      unsigned int datalen = ptlen + crypto_    
 55  *      u8 data[datalen];                         
 56  *      u8 *iv = data;                            
 57  *      u8 *pt = data + crypto_skcipher_ivsize    
 58  *              <ensure that pt contains the p    
 59  *      sg_init_one(&sg, pt, ptlen);              
 60  *      skcipher_request_set_crypt(req, &sg, &    
 61  *                                                
 62  *      ==> After encryption, data now contain    
 63  *                                                
 64  * In case of decryption, ciphertext now alrea    
 65  * and must be segmented appropriately:           
 66  *                                                
 67  *      unsigned int datalen = CTLEN;             
 68  *      u8 data[datalen];                         
 69  *              <ensure that data contains ful    
 70  *      u8 *iv = data;                            
 71  *      u8 *ct = data + crypto_skcipher_ivsize    
 72  *      unsigned int ctlen = datalen - crypto_    
 73  *      sg_init_one(&sg, ct, ctlen);              
 74  *      skcipher_request_set_crypt(req, &sg, &    
 75  *                                                
 76  *      ==> After decryption (which hopefully     
 77  *      pointer now points to the plaintext of    
 78  *                                                
 79  * Note 2: KWP is not implemented as this woul    
 80  *         If somebody wants to wrap non-align    
 81  *         the input with zeros to fill it up     
 82  */                                               
 83                                                   
 84 #include <linux/module.h>                         
 85 #include <linux/crypto.h>                         
 86 #include <linux/scatterlist.h>                    
 87 #include <crypto/scatterwalk.h>                   
 88 #include <crypto/internal/cipher.h>               
 89 #include <crypto/internal/skcipher.h>             
 90                                                   
 91 struct crypto_kw_block {                          
 92 #define SEMIBSIZE 8                               
 93         __be64 A;                                 
 94         __be64 R;                                 
 95 };                                                
 96                                                   
 97 /*                                                
 98  * Fast forward the SGL to the "end" length mi    
 99  * The start in the SGL defined by the fast-fo    
100  * the walk variable                              
101  */                                               
102 static void crypto_kw_scatterlist_ff(struct sc    
103                                      struct sc    
104                                      unsigned     
105 {                                                 
106         unsigned int skip = 0;                    
107                                                   
108         /* The caller should only operate on f    
109         BUG_ON(end < SEMIBSIZE);                  
110                                                   
111         skip = end - SEMIBSIZE;                   
112         while (sg) {                              
113                 if (sg->length > skip) {          
114                         scatterwalk_start(walk    
115                         scatterwalk_advance(wa    
116                         break;                    
117                 }                                 
118                                                   
119                 skip -= sg->length;               
120                 sg = sg_next(sg);                 
121         }                                         
122 }                                                 
123                                                   
124 static int crypto_kw_decrypt(struct skcipher_r    
125 {                                                 
126         struct crypto_skcipher *tfm = crypto_s    
127         struct crypto_cipher *cipher = skciphe    
128         struct crypto_kw_block block;             
129         struct scatterlist *src, *dst;            
130         u64 t = 6 * ((req->cryptlen) >> 3);       
131         unsigned int i;                           
132         int ret = 0;                              
133                                                   
134         /*                                        
135          * Require at least 2 semiblocks (note    
136          * required by SP800-38F is the IV.       
137          */                                       
138         if (req->cryptlen < (2 * SEMIBSIZE) ||    
139                 return -EINVAL;                   
140                                                   
141         /* Place the IV into block A */           
142         memcpy(&block.A, req->iv, SEMIBSIZE);     
143                                                   
144         /*                                        
145          * src scatterlist is read-only. dst s    
146          * first loop, src points to req->src     
147          * subsequent round, the code operates    
148          */                                       
149         src = req->src;                           
150         dst = req->dst;                           
151                                                   
152         for (i = 0; i < 6; i++) {                 
153                 struct scatter_walk src_walk,     
154                 unsigned int nbytes = req->cry    
155                                                   
156                 while (nbytes) {                  
157                         /* move pointer by nby    
158                         crypto_kw_scatterlist_    
159                         /* get the source bloc    
160                         scatterwalk_copychunks    
161                                                   
162                                                   
163                         /* perform KW operatio    
164                         block.A ^= cpu_to_be64    
165                         t--;                      
166                         /* perform KW operatio    
167                         crypto_cipher_decrypt_    
168                                                   
169                                                   
170                         /* move pointer by nby    
171                         crypto_kw_scatterlist_    
172                         /* Copy block->R into     
173                         scatterwalk_copychunks    
174                                                   
175                                                   
176                         nbytes -= SEMIBSIZE;      
177                 }                                 
178                                                   
179                 /* we now start to operate on     
180                 src = req->dst;                   
181                 dst = req->dst;                   
182         }                                         
183                                                   
184         /* Perform authentication check */        
185         if (block.A != cpu_to_be64(0xa6a6a6a6a    
186                 ret = -EBADMSG;                   
187                                                   
188         memzero_explicit(&block, sizeof(struct    
189                                                   
190         return ret;                               
191 }                                                 
192                                                   
193 static int crypto_kw_encrypt(struct skcipher_r    
194 {                                                 
195         struct crypto_skcipher *tfm = crypto_s    
196         struct crypto_cipher *cipher = skciphe    
197         struct crypto_kw_block block;             
198         struct scatterlist *src, *dst;            
199         u64 t = 1;                                
200         unsigned int i;                           
201                                                   
202         /*                                        
203          * Require at least 2 semiblocks (note    
204          * required by SP800-38F is the IV tha    
205          * This means that the dst memory must    
206          * Also ensure that the given data is     
207          */                                       
208         if (req->cryptlen < (2 * SEMIBSIZE) ||    
209                 return -EINVAL;                   
210                                                   
211         /*                                        
212          * Place the predefined IV into block     
213          * does not need to provide an IV, but    
214          */                                       
215         block.A = cpu_to_be64(0xa6a6a6a6a6a6a6    
216                                                   
217         /*                                        
218          * src scatterlist is read-only. dst s    
219          * first loop, src points to req->src     
220          * subsequent round, the code operates    
221          */                                       
222         src = req->src;                           
223         dst = req->dst;                           
224                                                   
225         for (i = 0; i < 6; i++) {                 
226                 struct scatter_walk src_walk,     
227                 unsigned int nbytes = req->cry    
228                                                   
229                 scatterwalk_start(&src_walk, s    
230                 scatterwalk_start(&dst_walk, d    
231                                                   
232                 while (nbytes) {                  
233                         /* get the source bloc    
234                         scatterwalk_copychunks    
235                                                   
236                                                   
237                         /* perform KW operatio    
238                         crypto_cipher_encrypt_    
239                                                   
240                         /* perform KW operatio    
241                         block.A ^= cpu_to_be64    
242                         t++;                      
243                                                   
244                         /* Copy block->R into     
245                         scatterwalk_copychunks    
246                                                   
247                                                   
248                         nbytes -= SEMIBSIZE;      
249                 }                                 
250                                                   
251                 /* we now start to operate on     
252                 src = req->dst;                   
253                 dst = req->dst;                   
254         }                                         
255                                                   
256         /* establish the IV for the caller to     
257         memcpy(req->iv, &block.A, SEMIBSIZE);     
258                                                   
259         memzero_explicit(&block, sizeof(struct    
260                                                   
261         return 0;                                 
262 }                                                 
263                                                   
264 static int crypto_kw_create(struct crypto_temp    
265 {                                                 
266         struct skcipher_instance *inst;           
267         struct crypto_alg *alg;                   
268         int err;                                  
269                                                   
270         inst = skcipher_alloc_instance_simple(    
271         if (IS_ERR(inst))                         
272                 return PTR_ERR(inst);             
273                                                   
274         alg = skcipher_ialg_simple(inst);         
275                                                   
276         err = -EINVAL;                            
277         /* Section 5.1 requirement for KW */      
278         if (alg->cra_blocksize != sizeof(struc    
279                 goto out_free_inst;               
280                                                   
281         inst->alg.base.cra_blocksize = SEMIBSI    
282         inst->alg.base.cra_alignmask = 0;         
283         inst->alg.ivsize = SEMIBSIZE;             
284                                                   
285         inst->alg.encrypt = crypto_kw_encrypt;    
286         inst->alg.decrypt = crypto_kw_decrypt;    
287                                                   
288         err = skcipher_register_instance(tmpl,    
289         if (err) {                                
290 out_free_inst:                                    
291                 inst->free(inst);                 
292         }                                         
293                                                   
294         return err;                               
295 }                                                 
296                                                   
297 static struct crypto_template crypto_kw_tmpl =    
298         .name = "kw",                             
299         .create = crypto_kw_create,               
300         .module = THIS_MODULE,                    
301 };                                                
302                                                   
303 static int __init crypto_kw_init(void)            
304 {                                                 
305         return crypto_register_template(&crypt    
306 }                                                 
307                                                   
308 static void __exit crypto_kw_exit(void)           
309 {                                                 
310         crypto_unregister_template(&crypto_kw_    
311 }                                                 
312                                                   
313 subsys_initcall(crypto_kw_init);                  
314 module_exit(crypto_kw_exit);                      
315                                                   
316 MODULE_LICENSE("Dual BSD/GPL");                   
317 MODULE_AUTHOR("Stephan Mueller <smueller@chron    
318 MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NI    
319 MODULE_ALIAS_CRYPTO("kw");                        
320 MODULE_IMPORT_NS(CRYPTO_INTERNAL);                
321                                                   

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