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

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


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /* XTS: as defined in IEEE1619/D16                
  3  *      http://grouper.ieee.org/groups/1619/em    
  4  *                                                
  5  * Copyright (c) 2007 Rik Snel <rsnel@cube.dyn    
  6  *                                                
  7  * Based on ecb.c                                 
  8  * Copyright (c) 2006 Herbert Xu <herbert@gond    
  9  */                                               
 10 #include <crypto/internal/cipher.h>               
 11 #include <crypto/internal/skcipher.h>             
 12 #include <crypto/scatterwalk.h>                   
 13 #include <linux/err.h>                            
 14 #include <linux/init.h>                           
 15 #include <linux/kernel.h>                         
 16 #include <linux/module.h>                         
 17 #include <linux/scatterlist.h>                    
 18 #include <linux/slab.h>                           
 19                                                   
 20 #include <crypto/xts.h>                           
 21 #include <crypto/b128ops.h>                       
 22 #include <crypto/gf128mul.h>                      
 23                                                   
 24 struct xts_tfm_ctx {                              
 25         struct crypto_skcipher *child;            
 26         struct crypto_cipher *tweak;              
 27 };                                                
 28                                                   
 29 struct xts_instance_ctx {                         
 30         struct crypto_skcipher_spawn spawn;       
 31         struct crypto_cipher_spawn tweak_spawn    
 32 };                                                
 33                                                   
 34 struct xts_request_ctx {                          
 35         le128 t;                                  
 36         struct scatterlist *tail;                 
 37         struct scatterlist sg[2];                 
 38         struct skcipher_request subreq;           
 39 };                                                
 40                                                   
 41 static int xts_setkey(struct crypto_skcipher *    
 42                       unsigned int keylen)        
 43 {                                                 
 44         struct xts_tfm_ctx *ctx = crypto_skcip    
 45         struct crypto_skcipher *child;            
 46         struct crypto_cipher *tweak;              
 47         int err;                                  
 48                                                   
 49         err = xts_verify_key(parent, key, keyl    
 50         if (err)                                  
 51                 return err;                       
 52                                                   
 53         keylen /= 2;                              
 54                                                   
 55         /* we need two cipher instances: one t    
 56          * by encrypting the IV (usually the '    
 57          * one to encrypt and decrypt the data    
 58                                                   
 59         /* tweak cipher, uses Key2 i.e. the se    
 60         tweak = ctx->tweak;                       
 61         crypto_cipher_clear_flags(tweak, CRYPT    
 62         crypto_cipher_set_flags(tweak, crypto_    
 63                                        CRYPTO_    
 64         err = crypto_cipher_setkey(tweak, key     
 65         if (err)                                  
 66                 return err;                       
 67                                                   
 68         /* data cipher, uses Key1 i.e. the fir    
 69         child = ctx->child;                       
 70         crypto_skcipher_clear_flags(child, CRY    
 71         crypto_skcipher_set_flags(child, crypt    
 72                                          CRYPT    
 73         return crypto_skcipher_setkey(child, k    
 74 }                                                 
 75                                                   
 76 /*                                                
 77  * We compute the tweak masks twice (both befo    
 78  * decryption) to avoid having to allocate a t    
 79  * mutliple calls to the 'ecb(..)' instance, w    
 80  * just doing the gf128mul_x_ble() calls again    
 81  */                                               
 82 static int xts_xor_tweak(struct skcipher_reque    
 83                          bool enc)                
 84 {                                                 
 85         struct xts_request_ctx *rctx = skciphe    
 86         struct crypto_skcipher *tfm = crypto_s    
 87         const bool cts = (req->cryptlen % XTS_    
 88         const int bs = XTS_BLOCK_SIZE;            
 89         struct skcipher_walk w;                   
 90         le128 t = rctx->t;                        
 91         int err;                                  
 92                                                   
 93         if (second_pass) {                        
 94                 req = &rctx->subreq;              
 95                 /* set to our TFM to enforce c    
 96                 skcipher_request_set_tfm(req,     
 97         }                                         
 98         err = skcipher_walk_virt(&w, req, fals    
 99                                                   
100         while (w.nbytes) {                        
101                 unsigned int avail = w.nbytes;    
102                 le128 *wsrc;                      
103                 le128 *wdst;                      
104                                                   
105                 wsrc = w.src.virt.addr;           
106                 wdst = w.dst.virt.addr;           
107                                                   
108                 do {                              
109                         if (unlikely(cts) &&      
110                             w.total - w.nbytes    
111                                 if (!enc) {       
112                                         if (se    
113                                                   
114                                         gf128m    
115                                 }                 
116                                 le128_xor(wdst    
117                                 if (enc && sec    
118                                         gf128m    
119                                 skcipher_walk_    
120                                 return 0;         
121                         }                         
122                                                   
123                         le128_xor(wdst++, &t,     
124                         gf128mul_x_ble(&t, &t)    
125                 } while ((avail -= bs) >= bs);    
126                                                   
127                 err = skcipher_walk_done(&w, a    
128         }                                         
129                                                   
130         return err;                               
131 }                                                 
132                                                   
133 static int xts_xor_tweak_pre(struct skcipher_r    
134 {                                                 
135         return xts_xor_tweak(req, false, enc);    
136 }                                                 
137                                                   
138 static int xts_xor_tweak_post(struct skcipher_    
139 {                                                 
140         return xts_xor_tweak(req, true, enc);     
141 }                                                 
142                                                   
143 static void xts_cts_done(void *data, int err)     
144 {                                                 
145         struct skcipher_request *req = data;      
146         le128 b;                                  
147                                                   
148         if (!err) {                               
149                 struct xts_request_ctx *rctx =    
150                                                   
151                 scatterwalk_map_and_copy(&b, r    
152                 le128_xor(&b, &rctx->t, &b);      
153                 scatterwalk_map_and_copy(&b, r    
154         }                                         
155                                                   
156         skcipher_request_complete(req, err);      
157 }                                                 
158                                                   
159 static int xts_cts_final(struct skcipher_reque    
160                          int (*crypt)(struct s    
161 {                                                 
162         const struct xts_tfm_ctx *ctx =           
163                 crypto_skcipher_ctx(crypto_skc    
164         int offset = req->cryptlen & ~(XTS_BLO    
165         struct xts_request_ctx *rctx = skciphe    
166         struct skcipher_request *subreq = &rct    
167         int tail = req->cryptlen % XTS_BLOCK_S    
168         le128 b[2];                               
169         int err;                                  
170                                                   
171         rctx->tail = scatterwalk_ffwd(rctx->sg    
172                                       offset -    
173                                                   
174         scatterwalk_map_and_copy(b, rctx->tail    
175         b[1] = b[0];                              
176         scatterwalk_map_and_copy(b, req->src,     
177                                                   
178         le128_xor(b, &rctx->t, b);                
179                                                   
180         scatterwalk_map_and_copy(b, rctx->tail    
181                                                   
182         skcipher_request_set_tfm(subreq, ctx->    
183         skcipher_request_set_callback(subreq,     
184                                       req);       
185         skcipher_request_set_crypt(subreq, rct    
186                                    XTS_BLOCK_S    
187                                                   
188         err = crypt(subreq);                      
189         if (err)                                  
190                 return err;                       
191                                                   
192         scatterwalk_map_and_copy(b, rctx->tail    
193         le128_xor(b, &rctx->t, b);                
194         scatterwalk_map_and_copy(b, rctx->tail    
195                                                   
196         return 0;                                 
197 }                                                 
198                                                   
199 static void xts_encrypt_done(void *data, int e    
200 {                                                 
201         struct skcipher_request *req = data;      
202                                                   
203         if (!err) {                               
204                 struct xts_request_ctx *rctx =    
205                                                   
206                 rctx->subreq.base.flags &= CRY    
207                 err = xts_xor_tweak_post(req,     
208                                                   
209                 if (!err && unlikely(req->cryp    
210                         err = xts_cts_final(re    
211                         if (err == -EINPROGRES    
212                                 return;           
213                 }                                 
214         }                                         
215                                                   
216         skcipher_request_complete(req, err);      
217 }                                                 
218                                                   
219 static void xts_decrypt_done(void *data, int e    
220 {                                                 
221         struct skcipher_request *req = data;      
222                                                   
223         if (!err) {                               
224                 struct xts_request_ctx *rctx =    
225                                                   
226                 rctx->subreq.base.flags &= CRY    
227                 err = xts_xor_tweak_post(req,     
228                                                   
229                 if (!err && unlikely(req->cryp    
230                         err = xts_cts_final(re    
231                         if (err == -EINPROGRES    
232                                 return;           
233                 }                                 
234         }                                         
235                                                   
236         skcipher_request_complete(req, err);      
237 }                                                 
238                                                   
239 static int xts_init_crypt(struct skcipher_requ    
240                           crypto_completion_t     
241 {                                                 
242         const struct xts_tfm_ctx *ctx =           
243                 crypto_skcipher_ctx(crypto_skc    
244         struct xts_request_ctx *rctx = skciphe    
245         struct skcipher_request *subreq = &rct    
246                                                   
247         if (req->cryptlen < XTS_BLOCK_SIZE)       
248                 return -EINVAL;                   
249                                                   
250         skcipher_request_set_tfm(subreq, ctx->    
251         skcipher_request_set_callback(subreq,     
252         skcipher_request_set_crypt(subreq, req    
253                                    req->cryptl    
254                                                   
255         /* calculate first value of T */          
256         crypto_cipher_encrypt_one(ctx->tweak,     
257                                                   
258         return 0;                                 
259 }                                                 
260                                                   
261 static int xts_encrypt(struct skcipher_request    
262 {                                                 
263         struct xts_request_ctx *rctx = skciphe    
264         struct skcipher_request *subreq = &rct    
265         int err;                                  
266                                                   
267         err = xts_init_crypt(req, xts_encrypt_    
268               xts_xor_tweak_pre(req, true) ?:     
269               crypto_skcipher_encrypt(subreq)     
270               xts_xor_tweak_post(req, true);      
271                                                   
272         if (err || likely((req->cryptlen % XTS    
273                 return err;                       
274                                                   
275         return xts_cts_final(req, crypto_skcip    
276 }                                                 
277                                                   
278 static int xts_decrypt(struct skcipher_request    
279 {                                                 
280         struct xts_request_ctx *rctx = skciphe    
281         struct skcipher_request *subreq = &rct    
282         int err;                                  
283                                                   
284         err = xts_init_crypt(req, xts_decrypt_    
285               xts_xor_tweak_pre(req, false) ?:    
286               crypto_skcipher_decrypt(subreq)     
287               xts_xor_tweak_post(req, false);     
288                                                   
289         if (err || likely((req->cryptlen % XTS    
290                 return err;                       
291                                                   
292         return xts_cts_final(req, crypto_skcip    
293 }                                                 
294                                                   
295 static int xts_init_tfm(struct crypto_skcipher    
296 {                                                 
297         struct skcipher_instance *inst = skcip    
298         struct xts_instance_ctx *ictx = skciph    
299         struct xts_tfm_ctx *ctx = crypto_skcip    
300         struct crypto_skcipher *child;            
301         struct crypto_cipher *tweak;              
302                                                   
303         child = crypto_spawn_skcipher(&ictx->s    
304         if (IS_ERR(child))                        
305                 return PTR_ERR(child);            
306                                                   
307         ctx->child = child;                       
308                                                   
309         tweak = crypto_spawn_cipher(&ictx->twe    
310         if (IS_ERR(tweak)) {                      
311                 crypto_free_skcipher(ctx->chil    
312                 return PTR_ERR(tweak);            
313         }                                         
314                                                   
315         ctx->tweak = tweak;                       
316                                                   
317         crypto_skcipher_set_reqsize(tfm, crypt    
318                                          sizeo    
319                                                   
320         return 0;                                 
321 }                                                 
322                                                   
323 static void xts_exit_tfm(struct crypto_skciphe    
324 {                                                 
325         struct xts_tfm_ctx *ctx = crypto_skcip    
326                                                   
327         crypto_free_skcipher(ctx->child);         
328         crypto_free_cipher(ctx->tweak);           
329 }                                                 
330                                                   
331 static void xts_free_instance(struct skcipher_    
332 {                                                 
333         struct xts_instance_ctx *ictx = skciph    
334                                                   
335         crypto_drop_skcipher(&ictx->spawn);       
336         crypto_drop_cipher(&ictx->tweak_spawn)    
337         kfree(inst);                              
338 }                                                 
339                                                   
340 static int xts_create(struct crypto_template *    
341 {                                                 
342         struct skcipher_alg_common *alg;          
343         char name[CRYPTO_MAX_ALG_NAME];           
344         struct skcipher_instance *inst;           
345         struct xts_instance_ctx *ctx;             
346         const char *cipher_name;                  
347         u32 mask;                                 
348         int err;                                  
349                                                   
350         err = crypto_check_attr_type(tb, CRYPT    
351         if (err)                                  
352                 return err;                       
353                                                   
354         cipher_name = crypto_attr_alg_name(tb[    
355         if (IS_ERR(cipher_name))                  
356                 return PTR_ERR(cipher_name);      
357                                                   
358         inst = kzalloc(sizeof(*inst) + sizeof(    
359         if (!inst)                                
360                 return -ENOMEM;                   
361                                                   
362         ctx = skcipher_instance_ctx(inst);        
363                                                   
364         err = crypto_grab_skcipher(&ctx->spawn    
365                                    cipher_name    
366         if (err == -ENOENT) {                     
367                 err = -ENAMETOOLONG;              
368                 if (snprintf(name, CRYPTO_MAX_    
369                              cipher_name) >= C    
370                         goto err_free_inst;       
371                                                   
372                 err = crypto_grab_skcipher(&ct    
373                                            skc    
374                                            nam    
375         }                                         
376                                                   
377         if (err)                                  
378                 goto err_free_inst;               
379                                                   
380         alg = crypto_spawn_skcipher_alg_common    
381                                                   
382         err = -EINVAL;                            
383         if (alg->base.cra_blocksize != XTS_BLO    
384                 goto err_free_inst;               
385                                                   
386         if (alg->ivsize)                          
387                 goto err_free_inst;               
388                                                   
389         err = crypto_inst_setname(skcipher_cry    
390                                   &alg->base);    
391         if (err)                                  
392                 goto err_free_inst;               
393                                                   
394         err = -EINVAL;                            
395         cipher_name = alg->base.cra_name;         
396                                                   
397         /* Alas we screwed up the naming so we    
398          * cipher name.                           
399          */                                       
400         if (!strncmp(cipher_name, "ecb(", 4))     
401                 int len;                          
402                                                   
403                 len = strscpy(name, cipher_nam    
404                 if (len < 2)                      
405                         goto err_free_inst;       
406                                                   
407                 if (name[len - 1] != ')')         
408                         goto err_free_inst;       
409                                                   
410                 name[len - 1] = 0;                
411                                                   
412                 if (snprintf(inst->alg.base.cr    
413                              "xts(%s)", name)     
414                         err = -ENAMETOOLONG;      
415                         goto err_free_inst;       
416                 }                                 
417         } else                                    
418                 goto err_free_inst;               
419                                                   
420         err = crypto_grab_cipher(&ctx->tweak_s    
421                                  skcipher_cryp    
422         if (err)                                  
423                 goto err_free_inst;               
424                                                   
425         inst->alg.base.cra_priority = alg->bas    
426         inst->alg.base.cra_blocksize = XTS_BLO    
427         inst->alg.base.cra_alignmask = alg->ba    
428                                        (__alig    
429                                                   
430         inst->alg.ivsize = XTS_BLOCK_SIZE;        
431         inst->alg.min_keysize = alg->min_keysi    
432         inst->alg.max_keysize = alg->max_keysi    
433                                                   
434         inst->alg.base.cra_ctxsize = sizeof(st    
435                                                   
436         inst->alg.init = xts_init_tfm;            
437         inst->alg.exit = xts_exit_tfm;            
438                                                   
439         inst->alg.setkey = xts_setkey;            
440         inst->alg.encrypt = xts_encrypt;          
441         inst->alg.decrypt = xts_decrypt;          
442                                                   
443         inst->free = xts_free_instance;           
444                                                   
445         err = skcipher_register_instance(tmpl,    
446         if (err) {                                
447 err_free_inst:                                    
448                 xts_free_instance(inst);          
449         }                                         
450         return err;                               
451 }                                                 
452                                                   
453 static struct crypto_template xts_tmpl = {        
454         .name = "xts",                            
455         .create = xts_create,                     
456         .module = THIS_MODULE,                    
457 };                                                
458                                                   
459 static int __init xts_module_init(void)           
460 {                                                 
461         return crypto_register_template(&xts_t    
462 }                                                 
463                                                   
464 static void __exit xts_module_exit(void)          
465 {                                                 
466         crypto_unregister_template(&xts_tmpl);    
467 }                                                 
468                                                   
469 subsys_initcall(xts_module_init);                 
470 module_exit(xts_module_exit);                     
471                                                   
472 MODULE_LICENSE("GPL");                            
473 MODULE_DESCRIPTION("XTS block cipher mode");      
474 MODULE_ALIAS_CRYPTO("xts");                       
475 MODULE_IMPORT_NS(CRYPTO_INTERNAL);                
476 MODULE_SOFTDEP("pre: ecb");                       
477                                                   

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