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

TOMOYO Linux Cross Reference
Linux/arch/s390/crypto/hmac_s390.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 /arch/s390/crypto/hmac_s390.c (Architecture m68k) and /arch/i386/crypto/hmac_s390.c (Architecture i386)


  1 // SPDX-License-Identifier: GPL-2.0+                1 
  2 /*                                                
  3  * Copyright IBM Corp. 2024                       
  4  *                                                
  5  * s390 specific HMAC support.                    
  6  */                                               
  7                                                   
  8 #define KMSG_COMPONENT  "hmac_s390"               
  9 #define pr_fmt(fmt)     KMSG_COMPONENT ": " fm    
 10                                                   
 11 #include <asm/cpacf.h>                            
 12 #include <crypto/sha2.h>                          
 13 #include <crypto/internal/hash.h>                 
 14 #include <linux/cpufeature.h>                     
 15 #include <linux/module.h>                         
 16                                                   
 17 /*                                                
 18  * KMAC param block layout for sha2 function c    
 19  * The layout of the param block for the KMAC     
 20  * blocksize of the used hashing sha2-algorith    
 21  * contains the hash chaining value (cv), the     
 22  * and the hmac-secret (key). To prevent code     
 23  * these are calculated based on the blocksize    
 24  *                                                
 25  * param-block:                                   
 26  * +-------+                                      
 27  * | cv    |                                      
 28  * +-------+                                      
 29  * | imbl  |                                      
 30  * +-------+                                      
 31  * | key   |                                      
 32  * +-------+                                      
 33  *                                                
 34  * sizes:                                         
 35  * part | sh2-alg | calculation | size | type     
 36  * -----+---------+-------------+------+------    
 37  * cv   | 224/256 | blocksize/2 |   32 |  u64[    
 38  *      | 384/512 |             |   64 | u128[    
 39  * imbl | 224/256 | blocksize/8 |    8 |     u    
 40  *      | 384/512 |             |   16 |    u1    
 41  * key  | 224/256 | blocksize   |   64 |  u8[6    
 42  *      | 384/512 |             |  128 | u8[12    
 43  */                                               
 44                                                   
 45 #define MAX_DIGEST_SIZE         SHA512_DIGEST_    
 46 #define MAX_IMBL_SIZE           sizeof(u128)      
 47 #define MAX_BLOCK_SIZE          SHA512_BLOCK_S    
 48                                                   
 49 #define SHA2_CV_SIZE(bs)        ((bs) >> 1)       
 50 #define SHA2_IMBL_SIZE(bs)      ((bs) >> 3)       
 51                                                   
 52 #define SHA2_IMBL_OFFSET(bs)    (SHA2_CV_SIZE(    
 53 #define SHA2_KEY_OFFSET(bs)     (SHA2_CV_SIZE(    
 54                                                   
 55 struct s390_hmac_ctx {                            
 56         u8 key[MAX_BLOCK_SIZE];                   
 57 };                                                
 58                                                   
 59 union s390_kmac_gr0 {                             
 60         unsigned long reg;                        
 61         struct {                                  
 62                 unsigned long           : 48;     
 63                 unsigned long ikp       :  1;     
 64                 unsigned long iimp      :  1;     
 65                 unsigned long ccup      :  1;     
 66                 unsigned long           :  6;     
 67                 unsigned long fc        :  7;     
 68         };                                        
 69 };                                                
 70                                                   
 71 struct s390_kmac_sha2_ctx {                       
 72         u8 param[MAX_DIGEST_SIZE + MAX_IMBL_SI    
 73         union s390_kmac_gr0 gr0;                  
 74         u8 buf[MAX_BLOCK_SIZE];                   
 75         unsigned int buflen;                      
 76 };                                                
 77                                                   
 78 /*                                                
 79  * kmac_sha2_set_imbl - sets the input message    
 80  */                                               
 81 static inline void kmac_sha2_set_imbl(u8 *para    
 82                                       unsigned    
 83 {                                                 
 84         u8 *imbl = param + SHA2_IMBL_OFFSET(bl    
 85                                                   
 86         switch (blocksize) {                      
 87         case SHA256_BLOCK_SIZE:                   
 88                 *(u64 *)imbl = (u64)buflen * B    
 89                 break;                            
 90         case SHA512_BLOCK_SIZE:                   
 91                 *(u128 *)imbl = (u128)buflen *    
 92                 break;                            
 93         default:                                  
 94                 break;                            
 95         }                                         
 96 }                                                 
 97                                                   
 98 static int hash_key(const u8 *in, unsigned int    
 99                     u8 *digest, unsigned int d    
100 {                                                 
101         unsigned long func;                       
102         union {                                   
103                 struct sha256_paramblock {        
104                         u32 h[8];                 
105                         u64 mbl;                  
106                 } sha256;                         
107                 struct sha512_paramblock {        
108                         u64 h[8];                 
109                         u128 mbl;                 
110                 } sha512;                         
111         } __packed param;                         
112                                                   
113 #define PARAM_INIT(x, y, z)                \      
114         param.sha##x.h[0] = SHA##y ## _H0; \      
115         param.sha##x.h[1] = SHA##y ## _H1; \      
116         param.sha##x.h[2] = SHA##y ## _H2; \      
117         param.sha##x.h[3] = SHA##y ## _H3; \      
118         param.sha##x.h[4] = SHA##y ## _H4; \      
119         param.sha##x.h[5] = SHA##y ## _H5; \      
120         param.sha##x.h[6] = SHA##y ## _H6; \      
121         param.sha##x.h[7] = SHA##y ## _H7; \      
122         param.sha##x.mbl = (z)                    
123                                                   
124         switch (digestsize) {                     
125         case SHA224_DIGEST_SIZE:                  
126                 func = CPACF_KLMD_SHA_256;        
127                 PARAM_INIT(256, 224, inlen * 8    
128                 break;                            
129         case SHA256_DIGEST_SIZE:                  
130                 func = CPACF_KLMD_SHA_256;        
131                 PARAM_INIT(256, 256, inlen * 8    
132                 break;                            
133         case SHA384_DIGEST_SIZE:                  
134                 func = CPACF_KLMD_SHA_512;        
135                 PARAM_INIT(512, 384, inlen * 8    
136                 break;                            
137         case SHA512_DIGEST_SIZE:                  
138                 func = CPACF_KLMD_SHA_512;        
139                 PARAM_INIT(512, 512, inlen * 8    
140                 break;                            
141         default:                                  
142                 return -EINVAL;                   
143         }                                         
144                                                   
145 #undef PARAM_INIT                                 
146                                                   
147         cpacf_klmd(func, &param, in, inlen);      
148                                                   
149         memcpy(digest, &param, digestsize);       
150                                                   
151         return 0;                                 
152 }                                                 
153                                                   
154 static int s390_hmac_sha2_setkey(struct crypto    
155                                  const u8 *key    
156 {                                                 
157         struct s390_hmac_ctx *tfm_ctx = crypto    
158         unsigned int ds = crypto_shash_digests    
159         unsigned int bs = crypto_shash_blocksi    
160                                                   
161         memset(tfm_ctx, 0, sizeof(*tfm_ctx));     
162                                                   
163         if (keylen > bs)                          
164                 return hash_key(key, keylen, t    
165                                                   
166         memcpy(tfm_ctx->key, key, keylen);        
167         return 0;                                 
168 }                                                 
169                                                   
170 static int s390_hmac_sha2_init(struct shash_de    
171 {                                                 
172         struct s390_hmac_ctx *tfm_ctx = crypto    
173         struct s390_kmac_sha2_ctx *ctx = shash    
174         unsigned int bs = crypto_shash_blocksi    
175                                                   
176         memcpy(ctx->param + SHA2_KEY_OFFSET(bs    
177                tfm_ctx->key, bs);                 
178                                                   
179         ctx->buflen = 0;                          
180         ctx->gr0.reg = 0;                         
181         switch (crypto_shash_digestsize(desc->    
182         case SHA224_DIGEST_SIZE:                  
183                 ctx->gr0.fc = CPACF_KMAC_HMAC_    
184                 break;                            
185         case SHA256_DIGEST_SIZE:                  
186                 ctx->gr0.fc = CPACF_KMAC_HMAC_    
187                 break;                            
188         case SHA384_DIGEST_SIZE:                  
189                 ctx->gr0.fc = CPACF_KMAC_HMAC_    
190                 break;                            
191         case SHA512_DIGEST_SIZE:                  
192                 ctx->gr0.fc = CPACF_KMAC_HMAC_    
193                 break;                            
194         default:                                  
195                 return -EINVAL;                   
196         }                                         
197                                                   
198         return 0;                                 
199 }                                                 
200                                                   
201 static int s390_hmac_sha2_update(struct shash_    
202                                  const u8 *dat    
203 {                                                 
204         struct s390_kmac_sha2_ctx *ctx = shash    
205         unsigned int bs = crypto_shash_blocksi    
206         unsigned int offset, n;                   
207                                                   
208         /* check current buffer */                
209         offset = ctx->buflen % bs;                
210         ctx->buflen += len;                       
211         if (offset + len < bs)                    
212                 goto store;                       
213                                                   
214         /* process one stored block */            
215         if (offset) {                             
216                 n = bs - offset;                  
217                 memcpy(ctx->buf + offset, data    
218                 ctx->gr0.iimp = 1;                
219                 _cpacf_kmac(&ctx->gr0.reg, ctx    
220                 data += n;                        
221                 len -= n;                         
222                 offset = 0;                       
223         }                                         
224         /* process as many blocks as possible     
225         if (len >= bs) {                          
226                 n = (len / bs) * bs;              
227                 ctx->gr0.iimp = 1;                
228                 _cpacf_kmac(&ctx->gr0.reg, ctx    
229                 data += n;                        
230                 len -= n;                         
231         }                                         
232 store:                                            
233         /* store incomplete block in buffer */    
234         if (len)                                  
235                 memcpy(ctx->buf + offset, data    
236                                                   
237         return 0;                                 
238 }                                                 
239                                                   
240 static int s390_hmac_sha2_final(struct shash_d    
241 {                                                 
242         struct s390_kmac_sha2_ctx *ctx = shash    
243         unsigned int bs = crypto_shash_blocksi    
244                                                   
245         ctx->gr0.iimp = 0;                        
246         kmac_sha2_set_imbl(ctx->param, ctx->bu    
247         _cpacf_kmac(&ctx->gr0.reg, ctx->param,    
248         memcpy(out, ctx->param, crypto_shash_d    
249                                                   
250         return 0;                                 
251 }                                                 
252                                                   
253 static int s390_hmac_sha2_digest(struct shash_    
254                                  const u8 *dat    
255 {                                                 
256         struct s390_kmac_sha2_ctx *ctx = shash    
257         unsigned int ds = crypto_shash_digests    
258         int rc;                                   
259                                                   
260         rc = s390_hmac_sha2_init(desc);           
261         if (rc)                                   
262                 return rc;                        
263                                                   
264         ctx->gr0.iimp = 0;                        
265         kmac_sha2_set_imbl(ctx->param, len,       
266                            crypto_shash_blocks    
267         _cpacf_kmac(&ctx->gr0.reg, ctx->param,    
268         memcpy(out, ctx->param, ds);              
269                                                   
270         return 0;                                 
271 }                                                 
272                                                   
273 #define S390_HMAC_SHA2_ALG(x) {                   
274         .fc = CPACF_KMAC_HMAC_SHA_##x,            
275         .alg = {                                  
276                 .init = s390_hmac_sha2_init,      
277                 .update = s390_hmac_sha2_updat    
278                 .final = s390_hmac_sha2_final,    
279                 .digest = s390_hmac_sha2_diges    
280                 .setkey = s390_hmac_sha2_setke    
281                 .descsize = sizeof(struct s390    
282                 .halg = {                         
283                         .digestsize = SHA##x##    
284                         .base = {                 
285                                 .cra_name = "h    
286                                 .cra_driver_na    
287                                 .cra_blocksize    
288                                 .cra_priority     
289                                 .cra_ctxsize =    
290                                 .cra_module =     
291                         },                        
292                 },                                
293         },                                        
294 }                                                 
295                                                   
296 static struct s390_hmac_alg {                     
297         bool registered;                          
298         unsigned int fc;                          
299         struct shash_alg alg;                     
300 } s390_hmac_algs[] = {                            
301         S390_HMAC_SHA2_ALG(224),                  
302         S390_HMAC_SHA2_ALG(256),                  
303         S390_HMAC_SHA2_ALG(384),                  
304         S390_HMAC_SHA2_ALG(512),                  
305 };                                                
306                                                   
307 static __always_inline void _s390_hmac_algs_un    
308 {                                                 
309         struct s390_hmac_alg *hmac;               
310         int i;                                    
311                                                   
312         for (i = ARRAY_SIZE(s390_hmac_algs) -     
313                 hmac = &s390_hmac_algs[i];        
314                 if (!hmac->registered)            
315                         continue;                 
316                 crypto_unregister_shash(&hmac-    
317         }                                         
318 }                                                 
319                                                   
320 static int __init hmac_s390_init(void)            
321 {                                                 
322         struct s390_hmac_alg *hmac;               
323         int i, rc = -ENODEV;                      
324                                                   
325         if (!cpacf_query_func(CPACF_KLMD, CPAC    
326                 return -ENODEV;                   
327         if (!cpacf_query_func(CPACF_KLMD, CPAC    
328                 return -ENODEV;                   
329                                                   
330         for (i = 0; i < ARRAY_SIZE(s390_hmac_a    
331                 hmac = &s390_hmac_algs[i];        
332                 if (!cpacf_query_func(CPACF_KM    
333                         continue;                 
334                                                   
335                 rc = crypto_register_shash(&hm    
336                 if (rc) {                         
337                         pr_err("unable to regi    
338                                hmac->alg.halg.    
339                         goto out;                 
340                 }                                 
341                 hmac->registered = true;          
342                 pr_debug("registered %s\n", hm    
343         }                                         
344         return rc;                                
345 out:                                              
346         _s390_hmac_algs_unregister();             
347         return rc;                                
348 }                                                 
349                                                   
350 static void __exit hmac_s390_exit(void)           
351 {                                                 
352         _s390_hmac_algs_unregister();             
353 }                                                 
354                                                   
355 module_cpu_feature_match(S390_CPU_FEATURE_MSA,    
356 module_exit(hmac_s390_exit);                      
357                                                   
358 MODULE_DESCRIPTION("S390 HMAC driver");           
359 MODULE_LICENSE("GPL");                            
360                                                   

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