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

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


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * HCTR2 length-preserving encryption mode        
  4  *                                                
  5  * Copyright 2021 Google LLC                      
  6  */                                               
  7                                                   
  8                                                   
  9 /*                                                
 10  * HCTR2 is a length-preserving encryption mod    
 11  * processors with instructions to accelerate     
 12  * multiplication, e.g. x86 processors with AE    
 13  * processors with the ARMv8 crypto extensions    
 14  *                                                
 15  * For more details, see the paper: "Length-pr    
 16  * (https://eprint.iacr.org/2021/1441.pdf)        
 17  */                                               
 18                                                   
 19 #include <crypto/internal/cipher.h>               
 20 #include <crypto/internal/hash.h>                 
 21 #include <crypto/internal/skcipher.h>             
 22 #include <crypto/polyval.h>                       
 23 #include <crypto/scatterwalk.h>                   
 24 #include <linux/module.h>                         
 25                                                   
 26 #define BLOCKCIPHER_BLOCK_SIZE          16        
 27                                                   
 28 /*                                                
 29  * The specification allows variable-length tw    
 30  * currently only allows algorithms to support    
 31  * tweak length for HCTR2 is 16, since that fi    
 32  * the best performance.  But longer tweaks ar    
 33  * needing to derive per-file keys.  So instea    
 34  */                                               
 35 #define TWEAK_SIZE              32                
 36                                                   
 37 struct hctr2_instance_ctx {                       
 38         struct crypto_cipher_spawn blockcipher    
 39         struct crypto_skcipher_spawn xctr_spaw    
 40         struct crypto_shash_spawn polyval_spaw    
 41 };                                                
 42                                                   
 43 struct hctr2_tfm_ctx {                            
 44         struct crypto_cipher *blockcipher;        
 45         struct crypto_skcipher *xctr;             
 46         struct crypto_shash *polyval;             
 47         u8 L[BLOCKCIPHER_BLOCK_SIZE];             
 48         int hashed_tweak_offset;                  
 49         /*                                        
 50          * This struct is allocated with extra    
 51          * states.  Since the hash state size     
 52          * can't add these to the struct direc    
 53          *                                        
 54          * hashed_tweaklen_divisible;             
 55          * hashed_tweaklen_remainder;             
 56          */                                       
 57 };                                                
 58                                                   
 59 struct hctr2_request_ctx {                        
 60         u8 first_block[BLOCKCIPHER_BLOCK_SIZE]    
 61         u8 xctr_iv[BLOCKCIPHER_BLOCK_SIZE];       
 62         struct scatterlist *bulk_part_dst;        
 63         struct scatterlist *bulk_part_src;        
 64         struct scatterlist sg_src[2];             
 65         struct scatterlist sg_dst[2];             
 66         /*                                        
 67          * Sub-request sizes are unknown at co    
 68          * after the members with known sizes.    
 69          */                                       
 70         union {                                   
 71                 struct shash_desc hash_desc;      
 72                 struct skcipher_request xctr_r    
 73         } u;                                      
 74         /*                                        
 75          * This struct is allocated with extra    
 76          * state.  Since the hash state size i    
 77          * can't add it to the struct directly    
 78          *                                        
 79          * hashed_tweak;                          
 80          */                                       
 81 };                                                
 82                                                   
 83 static inline u8 *hctr2_hashed_tweaklen(const     
 84                                         bool h    
 85 {                                                 
 86         u8 *p = (u8 *)tctx + sizeof(*tctx);       
 87                                                   
 88         if (has_remainder) /* For messages not    
 89                 p += crypto_shash_statesize(tc    
 90         return p;                                 
 91 }                                                 
 92                                                   
 93 static inline u8 *hctr2_hashed_tweak(const str    
 94                                      struct hc    
 95 {                                                 
 96         return (u8 *)rctx + tctx->hashed_tweak    
 97 }                                                 
 98                                                   
 99 /*                                                
100  * The input data for each HCTR2 hash step beg    
101  * contains the tweak length and a flag that i    
102  * divisible into blocks.  Since this implemen    
103  * length, we precompute the two hash states r    
104  * possible values of this initial block.  Thi    
105  * data that needs to be hashed for each encry    
106  *                                                
107  * These precomputed hashes are stored in hctr    
108  */                                               
109 static int hctr2_hash_tweaklen(struct hctr2_tf    
110 {                                                 
111         SHASH_DESC_ON_STACK(shash, tfm->polyva    
112         __le64 tweak_length_block[2];             
113         int err;                                  
114                                                   
115         shash->tfm = tctx->polyval;               
116         memset(tweak_length_block, 0, sizeof(t    
117                                                   
118         tweak_length_block[0] = cpu_to_le64(TW    
119         err = crypto_shash_init(shash);           
120         if (err)                                  
121                 return err;                       
122         err = crypto_shash_update(shash, (u8 *    
123                                   POLYVAL_BLOC    
124         if (err)                                  
125                 return err;                       
126         return crypto_shash_export(shash, hctr    
127 }                                                 
128                                                   
129 static int hctr2_setkey(struct crypto_skcipher    
130                         unsigned int keylen)      
131 {                                                 
132         struct hctr2_tfm_ctx *tctx = crypto_sk    
133         u8 hbar[BLOCKCIPHER_BLOCK_SIZE];          
134         int err;                                  
135                                                   
136         crypto_cipher_clear_flags(tctx->blockc    
137         crypto_cipher_set_flags(tctx->blockcip    
138                                 crypto_skciphe    
139                                 CRYPTO_TFM_REQ    
140         err = crypto_cipher_setkey(tctx->block    
141         if (err)                                  
142                 return err;                       
143                                                   
144         crypto_skcipher_clear_flags(tctx->xctr    
145         crypto_skcipher_set_flags(tctx->xctr,     
146                                   crypto_skcip    
147                                   CRYPTO_TFM_R    
148         err = crypto_skcipher_setkey(tctx->xct    
149         if (err)                                  
150                 return err;                       
151                                                   
152         memset(hbar, 0, sizeof(hbar));            
153         crypto_cipher_encrypt_one(tctx->blockc    
154                                                   
155         memset(tctx->L, 0, sizeof(tctx->L));      
156         tctx->L[0] = 0x01;                        
157         crypto_cipher_encrypt_one(tctx->blockc    
158                                                   
159         crypto_shash_clear_flags(tctx->polyval    
160         crypto_shash_set_flags(tctx->polyval,     
161                                CRYPTO_TFM_REQ_    
162         err = crypto_shash_setkey(tctx->polyva    
163         if (err)                                  
164                 return err;                       
165         memzero_explicit(hbar, sizeof(hbar));     
166                                                   
167         return hctr2_hash_tweaklen(tctx, true)    
168 }                                                 
169                                                   
170 static int hctr2_hash_tweak(struct skcipher_re    
171 {                                                 
172         struct crypto_skcipher *tfm = crypto_s    
173         const struct hctr2_tfm_ctx *tctx = cry    
174         struct hctr2_request_ctx *rctx = skcip    
175         struct shash_desc *hash_desc = &rctx->    
176         int err;                                  
177         bool has_remainder = req->cryptlen % P    
178                                                   
179         hash_desc->tfm = tctx->polyval;           
180         err = crypto_shash_import(hash_desc, h    
181         if (err)                                  
182                 return err;                       
183         err = crypto_shash_update(hash_desc, r    
184         if (err)                                  
185                 return err;                       
186                                                   
187         // Store the hashed tweak, since we ne    
188         // H(T || N) and H(T || V).               
189         return crypto_shash_export(hash_desc,     
190 }                                                 
191                                                   
192 static int hctr2_hash_message(struct skcipher_    
193                               struct scatterli    
194                               u8 digest[POLYVA    
195 {                                                 
196         static const u8 padding[BLOCKCIPHER_BL    
197         struct hctr2_request_ctx *rctx = skcip    
198         struct shash_desc *hash_desc = &rctx->    
199         const unsigned int bulk_len = req->cry    
200         struct sg_mapping_iter miter;             
201         unsigned int remainder = bulk_len % BL    
202         int i;                                    
203         int err = 0;                              
204         int n = 0;                                
205                                                   
206         sg_miter_start(&miter, sgl, sg_nents(s    
207                        SG_MITER_FROM_SG | SG_M    
208         for (i = 0; i < bulk_len; i += n) {       
209                 sg_miter_next(&miter);            
210                 n = min_t(unsigned int, miter.    
211                 err = crypto_shash_update(hash    
212                 if (err)                          
213                         break;                    
214         }                                         
215         sg_miter_stop(&miter);                    
216                                                   
217         if (err)                                  
218                 return err;                       
219                                                   
220         if (remainder) {                          
221                 err = crypto_shash_update(hash    
222                                           BLOC    
223                 if (err)                          
224                         return err;               
225         }                                         
226         return crypto_shash_final(hash_desc, d    
227 }                                                 
228                                                   
229 static int hctr2_finish(struct skcipher_reques    
230 {                                                 
231         struct crypto_skcipher *tfm = crypto_s    
232         const struct hctr2_tfm_ctx *tctx = cry    
233         struct hctr2_request_ctx *rctx = skcip    
234         u8 digest[POLYVAL_DIGEST_SIZE];           
235         struct shash_desc *hash_desc = &rctx->    
236         int err;                                  
237                                                   
238         // U = UU ^ H(T || V)                     
239         // or M = MM ^ H(T || N)                  
240         hash_desc->tfm = tctx->polyval;           
241         err = crypto_shash_import(hash_desc, h    
242         if (err)                                  
243                 return err;                       
244         err = hctr2_hash_message(req, rctx->bu    
245         if (err)                                  
246                 return err;                       
247         crypto_xor(rctx->first_block, digest,     
248                                                   
249         // Copy U (or M) into dst scatterlist     
250         scatterwalk_map_and_copy(rctx->first_b    
251                                  0, BLOCKCIPHE    
252         return 0;                                 
253 }                                                 
254                                                   
255 static void hctr2_xctr_done(void *data, int er    
256 {                                                 
257         struct skcipher_request *req = data;      
258                                                   
259         if (!err)                                 
260                 err = hctr2_finish(req);          
261                                                   
262         skcipher_request_complete(req, err);      
263 }                                                 
264                                                   
265 static int hctr2_crypt(struct skcipher_request    
266 {                                                 
267         struct crypto_skcipher *tfm = crypto_s    
268         const struct hctr2_tfm_ctx *tctx = cry    
269         struct hctr2_request_ctx *rctx = skcip    
270         u8 digest[POLYVAL_DIGEST_SIZE];           
271         int bulk_len = req->cryptlen - BLOCKCI    
272         int err;                                  
273                                                   
274         // Requests must be at least one block    
275         if (req->cryptlen < BLOCKCIPHER_BLOCK_    
276                 return -EINVAL;                   
277                                                   
278         // Copy M (or U) into a temporary buff    
279         scatterwalk_map_and_copy(rctx->first_b    
280                                  0, BLOCKCIPHE    
281                                                   
282         // Create scatterlists for N and V        
283         rctx->bulk_part_src = scatterwalk_ffwd    
284                                                   
285         rctx->bulk_part_dst = scatterwalk_ffwd    
286                                                   
287                                                   
288         // MM = M ^ H(T || N)                     
289         // or UU = U ^ H(T || V)                  
290         err = hctr2_hash_tweak(req);              
291         if (err)                                  
292                 return err;                       
293         err = hctr2_hash_message(req, rctx->bu    
294         if (err)                                  
295                 return err;                       
296         crypto_xor(digest, rctx->first_block,     
297                                                   
298         // UU = E(MM)                             
299         // or MM = D(UU)                          
300         if (enc)                                  
301                 crypto_cipher_encrypt_one(tctx    
302                                           dige    
303         else                                      
304                 crypto_cipher_decrypt_one(tctx    
305                                           dige    
306                                                   
307         // S = MM ^ UU ^ L                        
308         crypto_xor(digest, rctx->first_block,     
309         crypto_xor_cpy(rctx->xctr_iv, digest,     
310                                                   
311         // V = XCTR(S, N)                         
312         // or N = XCTR(S, V)                      
313         skcipher_request_set_tfm(&rctx->u.xctr    
314         skcipher_request_set_crypt(&rctx->u.xc    
315                                    rctx->bulk_    
316                                    rctx->xctr_    
317         skcipher_request_set_callback(&rctx->u    
318                                       req->bas    
319                                       hctr2_xc    
320         return crypto_skcipher_encrypt(&rctx->    
321                 hctr2_finish(req);                
322 }                                                 
323                                                   
324 static int hctr2_encrypt(struct skcipher_reque    
325 {                                                 
326         return hctr2_crypt(req, true);            
327 }                                                 
328                                                   
329 static int hctr2_decrypt(struct skcipher_reque    
330 {                                                 
331         return hctr2_crypt(req, false);           
332 }                                                 
333                                                   
334 static int hctr2_init_tfm(struct crypto_skciph    
335 {                                                 
336         struct skcipher_instance *inst = skcip    
337         struct hctr2_instance_ctx *ictx = skci    
338         struct hctr2_tfm_ctx *tctx = crypto_sk    
339         struct crypto_skcipher *xctr;             
340         struct crypto_cipher *blockcipher;        
341         struct crypto_shash *polyval;             
342         unsigned int subreq_size;                 
343         int err;                                  
344                                                   
345         xctr = crypto_spawn_skcipher(&ictx->xc    
346         if (IS_ERR(xctr))                         
347                 return PTR_ERR(xctr);             
348                                                   
349         blockcipher = crypto_spawn_cipher(&ict    
350         if (IS_ERR(blockcipher)) {                
351                 err = PTR_ERR(blockcipher);       
352                 goto err_free_xctr;               
353         }                                         
354                                                   
355         polyval = crypto_spawn_shash(&ictx->po    
356         if (IS_ERR(polyval)) {                    
357                 err = PTR_ERR(polyval);           
358                 goto err_free_blockcipher;        
359         }                                         
360                                                   
361         tctx->xctr = xctr;                        
362         tctx->blockcipher = blockcipher;          
363         tctx->polyval = polyval;                  
364                                                   
365         BUILD_BUG_ON(offsetofend(struct hctr2_    
366                                  sizeof(struct    
367         subreq_size = max(sizeof_field(struct     
368                           crypto_shash_descsiz    
369                           sizeof_field(struct     
370                           crypto_skcipher_reqs    
371                                                   
372         tctx->hashed_tweak_offset = offsetof(s    
373                                     subreq_siz    
374         crypto_skcipher_set_reqsize(tfm, tctx-    
375                                     crypto_sha    
376         return 0;                                 
377                                                   
378 err_free_blockcipher:                             
379         crypto_free_cipher(blockcipher);          
380 err_free_xctr:                                    
381         crypto_free_skcipher(xctr);               
382         return err;                               
383 }                                                 
384                                                   
385 static void hctr2_exit_tfm(struct crypto_skcip    
386 {                                                 
387         struct hctr2_tfm_ctx *tctx = crypto_sk    
388                                                   
389         crypto_free_cipher(tctx->blockcipher);    
390         crypto_free_skcipher(tctx->xctr);         
391         crypto_free_shash(tctx->polyval);         
392 }                                                 
393                                                   
394 static void hctr2_free_instance(struct skciphe    
395 {                                                 
396         struct hctr2_instance_ctx *ictx = skci    
397                                                   
398         crypto_drop_cipher(&ictx->blockcipher_    
399         crypto_drop_skcipher(&ictx->xctr_spawn    
400         crypto_drop_shash(&ictx->polyval_spawn    
401         kfree(inst);                              
402 }                                                 
403                                                   
404 static int hctr2_create_common(struct crypto_t    
405                                struct rtattr *    
406                                const char *xct    
407                                const char *pol    
408 {                                                 
409         struct skcipher_alg_common *xctr_alg;     
410         u32 mask;                                 
411         struct skcipher_instance *inst;           
412         struct hctr2_instance_ctx *ictx;          
413         struct crypto_alg *blockcipher_alg;       
414         struct shash_alg *polyval_alg;            
415         char blockcipher_name[CRYPTO_MAX_ALG_N    
416         int len;                                  
417         int err;                                  
418                                                   
419         err = crypto_check_attr_type(tb, CRYPT    
420         if (err)                                  
421                 return err;                       
422                                                   
423         inst = kzalloc(sizeof(*inst) + sizeof(    
424         if (!inst)                                
425                 return -ENOMEM;                   
426         ictx = skcipher_instance_ctx(inst);       
427                                                   
428         /* Stream cipher, xctr(block_cipher) *    
429         err = crypto_grab_skcipher(&ictx->xctr    
430                                    skcipher_cr    
431                                    xctr_name,     
432         if (err)                                  
433                 goto err_free_inst;               
434         xctr_alg = crypto_spawn_skcipher_alg_c    
435                                                   
436         err = -EINVAL;                            
437         if (strncmp(xctr_alg->base.cra_name, "    
438                 goto err_free_inst;               
439         len = strscpy(blockcipher_name, xctr_a    
440                       sizeof(blockcipher_name)    
441         if (len < 1)                              
442                 goto err_free_inst;               
443         if (blockcipher_name[len - 1] != ')')     
444                 goto err_free_inst;               
445         blockcipher_name[len - 1] = 0;            
446                                                   
447         /* Block cipher, e.g. "aes" */            
448         err = crypto_grab_cipher(&ictx->blockc    
449                                  skcipher_cryp    
450                                  blockcipher_n    
451         if (err)                                  
452                 goto err_free_inst;               
453         blockcipher_alg = crypto_spawn_cipher_    
454                                                   
455         /* Require blocksize of 16 bytes */       
456         err = -EINVAL;                            
457         if (blockcipher_alg->cra_blocksize !=     
458                 goto err_free_inst;               
459                                                   
460         /* Polyval ε-∆U hash function */       
461         err = crypto_grab_shash(&ictx->polyval    
462                                 skcipher_crypt    
463                                 polyval_name,     
464         if (err)                                  
465                 goto err_free_inst;               
466         polyval_alg = crypto_spawn_shash_alg(&    
467                                                   
468         /* Ensure Polyval is being used */        
469         err = -EINVAL;                            
470         if (strcmp(polyval_alg->base.cra_name,    
471                 goto err_free_inst;               
472                                                   
473         /* Instance fields */                     
474                                                   
475         err = -ENAMETOOLONG;                      
476         if (snprintf(inst->alg.base.cra_name,     
477                      blockcipher_alg->cra_name    
478                 goto err_free_inst;               
479         if (snprintf(inst->alg.base.cra_driver    
480                      "hctr2_base(%s,%s)",         
481                      xctr_alg->base.cra_driver    
482                      polyval_alg->base.cra_dri    
483                 goto err_free_inst;               
484                                                   
485         inst->alg.base.cra_blocksize = BLOCKCI    
486         inst->alg.base.cra_ctxsize = sizeof(st    
487                                      polyval_a    
488         inst->alg.base.cra_alignmask = xctr_al    
489         /*                                        
490          * The hash function is called twice,     
491          * xctr and blockcipher.                  
492          */                                       
493         inst->alg.base.cra_priority = (2 * xct    
494                                        4 * pol    
495                                        blockci    
496                                                   
497         inst->alg.setkey = hctr2_setkey;          
498         inst->alg.encrypt = hctr2_encrypt;        
499         inst->alg.decrypt = hctr2_decrypt;        
500         inst->alg.init = hctr2_init_tfm;          
501         inst->alg.exit = hctr2_exit_tfm;          
502         inst->alg.min_keysize = xctr_alg->min_    
503         inst->alg.max_keysize = xctr_alg->max_    
504         inst->alg.ivsize = TWEAK_SIZE;            
505                                                   
506         inst->free = hctr2_free_instance;         
507                                                   
508         err = skcipher_register_instance(tmpl,    
509         if (err) {                                
510 err_free_inst:                                    
511                 hctr2_free_instance(inst);        
512         }                                         
513         return err;                               
514 }                                                 
515                                                   
516 static int hctr2_create_base(struct crypto_tem    
517 {                                                 
518         const char *xctr_name;                    
519         const char *polyval_name;                 
520                                                   
521         xctr_name = crypto_attr_alg_name(tb[1]    
522         if (IS_ERR(xctr_name))                    
523                 return PTR_ERR(xctr_name);        
524                                                   
525         polyval_name = crypto_attr_alg_name(tb    
526         if (IS_ERR(polyval_name))                 
527                 return PTR_ERR(polyval_name);     
528                                                   
529         return hctr2_create_common(tmpl, tb, x    
530 }                                                 
531                                                   
532 static int hctr2_create(struct crypto_template    
533 {                                                 
534         const char *blockcipher_name;             
535         char xctr_name[CRYPTO_MAX_ALG_NAME];      
536                                                   
537         blockcipher_name = crypto_attr_alg_nam    
538         if (IS_ERR(blockcipher_name))             
539                 return PTR_ERR(blockcipher_nam    
540                                                   
541         if (snprintf(xctr_name, CRYPTO_MAX_ALG    
542                     blockcipher_name) >= CRYPT    
543                 return -ENAMETOOLONG;             
544                                                   
545         return hctr2_create_common(tmpl, tb, x    
546 }                                                 
547                                                   
548 static struct crypto_template hctr2_tmpls[] =     
549         {                                         
550                 /* hctr2_base(xctr_name, polyv    
551                 .name = "hctr2_base",             
552                 .create = hctr2_create_base,      
553                 .module = THIS_MODULE,            
554         }, {                                      
555                 /* hctr2(blockcipher_name) */     
556                 .name = "hctr2",                  
557                 .create = hctr2_create,           
558                 .module = THIS_MODULE,            
559         }                                         
560 };                                                
561                                                   
562 static int __init hctr2_module_init(void)         
563 {                                                 
564         return crypto_register_templates(hctr2    
565 }                                                 
566                                                   
567 static void __exit hctr2_module_exit(void)        
568 {                                                 
569         return crypto_unregister_templates(hct    
570                                            ARR    
571 }                                                 
572                                                   
573 subsys_initcall(hctr2_module_init);               
574 module_exit(hctr2_module_exit);                   
575                                                   
576 MODULE_DESCRIPTION("HCTR2 length-preserving en    
577 MODULE_LICENSE("GPL v2");                         
578 MODULE_ALIAS_CRYPTO("hctr2");                     
579 MODULE_IMPORT_NS(CRYPTO_INTERNAL);                
580                                                   

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