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

TOMOYO Linux Cross Reference
Linux/arch/s390/crypto/prng.c

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.15 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.73 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.144 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.193 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.193 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.73 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright IBM Corp. 2006, 2015
  3  * Author(s): Jan Glauber <jan.glauber@de.ibm.com>
  4  *            Harald Freudenberger <freude@de.ibm.com>
  5  * Driver for the s390 pseudo random number generator
  6  */
  7 
  8 #define KMSG_COMPONENT "prng"
  9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 10 
 11 #include <linux/fs.h>
 12 #include <linux/fips.h>
 13 #include <linux/init.h>
 14 #include <linux/kernel.h>
 15 #include <linux/device.h>
 16 #include <linux/miscdevice.h>
 17 #include <linux/module.h>
 18 #include <linux/moduleparam.h>
 19 #include <linux/mutex.h>
 20 #include <linux/cpufeature.h>
 21 #include <linux/random.h>
 22 #include <linux/slab.h>
 23 #include <asm/debug.h>
 24 #include <linux/uaccess.h>
 25 #include <asm/timex.h>
 26 #include <asm/cpacf.h>
 27 
 28 MODULE_LICENSE("GPL");
 29 MODULE_AUTHOR("IBM Corporation");
 30 MODULE_DESCRIPTION("s390 PRNG interface");
 31 
 32 
 33 #define PRNG_MODE_AUTO    0
 34 #define PRNG_MODE_TDES    1
 35 #define PRNG_MODE_SHA512  2
 36 
 37 static unsigned int prng_mode = PRNG_MODE_AUTO;
 38 module_param_named(mode, prng_mode, int, 0);
 39 MODULE_PARM_DESC(prng_mode, "PRNG mode: 0 - auto, 1 - TDES, 2 - SHA512");
 40 
 41 
 42 #define PRNG_CHUNKSIZE_TDES_MIN   8
 43 #define PRNG_CHUNKSIZE_TDES_MAX   (64*1024)
 44 #define PRNG_CHUNKSIZE_SHA512_MIN 64
 45 #define PRNG_CHUNKSIZE_SHA512_MAX (64*1024)
 46 
 47 static unsigned int prng_chunk_size = 256;
 48 module_param_named(chunksize, prng_chunk_size, int, 0);
 49 MODULE_PARM_DESC(prng_chunk_size, "PRNG read chunk size in bytes");
 50 
 51 
 52 #define PRNG_RESEED_LIMIT_TDES           4096
 53 #define PRNG_RESEED_LIMIT_TDES_LOWER     4096
 54 #define PRNG_RESEED_LIMIT_SHA512       100000
 55 #define PRNG_RESEED_LIMIT_SHA512_LOWER  10000
 56 
 57 static unsigned int prng_reseed_limit;
 58 module_param_named(reseed_limit, prng_reseed_limit, int, 0);
 59 MODULE_PARM_DESC(prng_reseed_limit, "PRNG reseed limit");
 60 
 61 
 62 /*
 63  * Any one who considers arithmetical methods of producing random digits is,
 64  * of course, in a state of sin. -- John von Neumann
 65  */
 66 
 67 static int prng_errorflag;
 68 
 69 #define PRNG_GEN_ENTROPY_FAILED  1
 70 #define PRNG_SELFTEST_FAILED     2
 71 #define PRNG_INSTANTIATE_FAILED  3
 72 #define PRNG_SEED_FAILED         4
 73 #define PRNG_RESEED_FAILED       5
 74 #define PRNG_GEN_FAILED          6
 75 
 76 struct prng_ws_s {
 77         u8  parm_block[32];
 78         u32 reseed_counter;
 79         u64 byte_counter;
 80 };
 81 
 82 struct ppno_ws_s {
 83         u32 res;
 84         u32 reseed_counter;
 85         u64 stream_bytes;
 86         u8  V[112];
 87         u8  C[112];
 88 };
 89 
 90 struct prng_data_s {
 91         struct mutex mutex;
 92         union {
 93                 struct prng_ws_s prngws;
 94                 struct ppno_ws_s ppnows;
 95         };
 96         u8 *buf;
 97         u32 rest;
 98         u8 *prev;
 99 };
100 
101 static struct prng_data_s *prng_data;
102 
103 /* initial parameter block for tdes mode, copied from libica */
104 static const u8 initial_parm_block[32] __initconst = {
105         0x0F, 0x2B, 0x8E, 0x63, 0x8C, 0x8E, 0xD2, 0x52,
106         0x64, 0xB7, 0xA0, 0x7B, 0x75, 0x28, 0xB8, 0xF4,
107         0x75, 0x5F, 0xD2, 0xA6, 0x8D, 0x97, 0x11, 0xFF,
108         0x49, 0xD8, 0x23, 0xF3, 0x7E, 0x21, 0xEC, 0xA0 };
109 
110 
111 /*** helper functions ***/
112 
113 static int generate_entropy(u8 *ebuf, size_t nbytes)
114 {
115         int n, ret = 0;
116         u8 *pg, *h, hash[32];
117 
118         pg = (u8 *) __get_free_page(GFP_KERNEL);
119         if (!pg) {
120                 prng_errorflag = PRNG_GEN_ENTROPY_FAILED;
121                 return -ENOMEM;
122         }
123 
124         while (nbytes) {
125                 /* fill page with urandom bytes */
126                 get_random_bytes(pg, PAGE_SIZE);
127                 /* exor page with stckf values */
128                 for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) {
129                         u64 *p = ((u64 *)pg) + n;
130                         *p ^= get_tod_clock_fast();
131                 }
132                 n = (nbytes < sizeof(hash)) ? nbytes : sizeof(hash);
133                 if (n < sizeof(hash))
134                         h = hash;
135                 else
136                         h = ebuf;
137                 /* generate sha256 from this page */
138                 cpacf_kimd(CPACF_KIMD_SHA_256, h, pg, PAGE_SIZE);
139                 if (n < sizeof(hash))
140                         memcpy(ebuf, hash, n);
141                 ret += n;
142                 ebuf += n;
143                 nbytes -= n;
144         }
145 
146         free_page((unsigned long)pg);
147         return ret;
148 }
149 
150 
151 /*** tdes functions ***/
152 
153 static void prng_tdes_add_entropy(void)
154 {
155         __u64 entropy[4];
156         unsigned int i;
157 
158         for (i = 0; i < 16; i++) {
159                 cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
160                           (char *) entropy, (char *) entropy,
161                           sizeof(entropy));
162                 memcpy(prng_data->prngws.parm_block, entropy, sizeof(entropy));
163         }
164 }
165 
166 
167 static void prng_tdes_seed(int nbytes)
168 {
169         char buf[16];
170         int i = 0;
171 
172         BUG_ON(nbytes > sizeof(buf));
173 
174         get_random_bytes(buf, nbytes);
175 
176         /* Add the entropy */
177         while (nbytes >= 8) {
178                 *((__u64 *)prng_data->prngws.parm_block) ^= *((__u64 *)(buf+i));
179                 prng_tdes_add_entropy();
180                 i += 8;
181                 nbytes -= 8;
182         }
183         prng_tdes_add_entropy();
184         prng_data->prngws.reseed_counter = 0;
185 }
186 
187 
188 static int __init prng_tdes_instantiate(void)
189 {
190         int datalen;
191 
192         pr_debug("prng runs in TDES mode with "
193                  "chunksize=%d and reseed_limit=%u\n",
194                  prng_chunk_size, prng_reseed_limit);
195 
196         /* memory allocation, prng_data struct init, mutex init */
197         datalen = sizeof(struct prng_data_s) + prng_chunk_size;
198         prng_data = kzalloc(datalen, GFP_KERNEL);
199         if (!prng_data) {
200                 prng_errorflag = PRNG_INSTANTIATE_FAILED;
201                 return -ENOMEM;
202         }
203         mutex_init(&prng_data->mutex);
204         prng_data->buf = ((u8 *)prng_data) + sizeof(struct prng_data_s);
205         memcpy(prng_data->prngws.parm_block, initial_parm_block, 32);
206 
207         /* initialize the PRNG, add 128 bits of entropy */
208         prng_tdes_seed(16);
209 
210         return 0;
211 }
212 
213 
214 static void prng_tdes_deinstantiate(void)
215 {
216         pr_debug("The prng module stopped "
217                  "after running in triple DES mode\n");
218         kzfree(prng_data);
219 }
220 
221 
222 /*** sha512 functions ***/
223 
224 static int __init prng_sha512_selftest(void)
225 {
226         /* NIST DRBG testvector for Hash Drbg, Sha-512, Count #0 */
227         static const u8 seed[] __initconst = {
228                 0x6b, 0x50, 0xa7, 0xd8, 0xf8, 0xa5, 0x5d, 0x7a,
229                 0x3d, 0xf8, 0xbb, 0x40, 0xbc, 0xc3, 0xb7, 0x22,
230                 0xd8, 0x70, 0x8d, 0xe6, 0x7f, 0xda, 0x01, 0x0b,
231                 0x03, 0xc4, 0xc8, 0x4d, 0x72, 0x09, 0x6f, 0x8c,
232                 0x3e, 0xc6, 0x49, 0xcc, 0x62, 0x56, 0xd9, 0xfa,
233                 0x31, 0xdb, 0x7a, 0x29, 0x04, 0xaa, 0xf0, 0x25 };
234         static const u8 V0[] __initconst = {
235                 0x00, 0xad, 0xe3, 0x6f, 0x9a, 0x01, 0xc7, 0x76,
236                 0x61, 0x34, 0x35, 0xf5, 0x4e, 0x24, 0x74, 0x22,
237                 0x21, 0x9a, 0x29, 0x89, 0xc7, 0x93, 0x2e, 0x60,
238                 0x1e, 0xe8, 0x14, 0x24, 0x8d, 0xd5, 0x03, 0xf1,
239                 0x65, 0x5d, 0x08, 0x22, 0x72, 0xd5, 0xad, 0x95,
240                 0xe1, 0x23, 0x1e, 0x8a, 0xa7, 0x13, 0xd9, 0x2b,
241                 0x5e, 0xbc, 0xbb, 0x80, 0xab, 0x8d, 0xe5, 0x79,
242                 0xab, 0x5b, 0x47, 0x4e, 0xdd, 0xee, 0x6b, 0x03,
243                 0x8f, 0x0f, 0x5c, 0x5e, 0xa9, 0x1a, 0x83, 0xdd,
244                 0xd3, 0x88, 0xb2, 0x75, 0x4b, 0xce, 0x83, 0x36,
245                 0x57, 0x4b, 0xf1, 0x5c, 0xca, 0x7e, 0x09, 0xc0,
246                 0xd3, 0x89, 0xc6, 0xe0, 0xda, 0xc4, 0x81, 0x7e,
247                 0x5b, 0xf9, 0xe1, 0x01, 0xc1, 0x92, 0x05, 0xea,
248                 0xf5, 0x2f, 0xc6, 0xc6, 0xc7, 0x8f, 0xbc, 0xf4 };
249         static const u8 C0[] __initconst = {
250                 0x00, 0xf4, 0xa3, 0xe5, 0xa0, 0x72, 0x63, 0x95,
251                 0xc6, 0x4f, 0x48, 0xd0, 0x8b, 0x5b, 0x5f, 0x8e,
252                 0x6b, 0x96, 0x1f, 0x16, 0xed, 0xbc, 0x66, 0x94,
253                 0x45, 0x31, 0xd7, 0x47, 0x73, 0x22, 0xa5, 0x86,
254                 0xce, 0xc0, 0x4c, 0xac, 0x63, 0xb8, 0x39, 0x50,
255                 0xbf, 0xe6, 0x59, 0x6c, 0x38, 0x58, 0x99, 0x1f,
256                 0x27, 0xa7, 0x9d, 0x71, 0x2a, 0xb3, 0x7b, 0xf9,
257                 0xfb, 0x17, 0x86, 0xaa, 0x99, 0x81, 0xaa, 0x43,
258                 0xe4, 0x37, 0xd3, 0x1e, 0x6e, 0xe5, 0xe6, 0xee,
259                 0xc2, 0xed, 0x95, 0x4f, 0x53, 0x0e, 0x46, 0x8a,
260                 0xcc, 0x45, 0xa5, 0xdb, 0x69, 0x0d, 0x81, 0xc9,
261                 0x32, 0x92, 0xbc, 0x8f, 0x33, 0xe6, 0xf6, 0x09,
262                 0x7c, 0x8e, 0x05, 0x19, 0x0d, 0xf1, 0xb6, 0xcc,
263                 0xf3, 0x02, 0x21, 0x90, 0x25, 0xec, 0xed, 0x0e };
264         static const u8 random[] __initconst = {
265                 0x95, 0xb7, 0xf1, 0x7e, 0x98, 0x02, 0xd3, 0x57,
266                 0x73, 0x92, 0xc6, 0xa9, 0xc0, 0x80, 0x83, 0xb6,
267                 0x7d, 0xd1, 0x29, 0x22, 0x65, 0xb5, 0xf4, 0x2d,
268                 0x23, 0x7f, 0x1c, 0x55, 0xbb, 0x9b, 0x10, 0xbf,
269                 0xcf, 0xd8, 0x2c, 0x77, 0xa3, 0x78, 0xb8, 0x26,
270                 0x6a, 0x00, 0x99, 0x14, 0x3b, 0x3c, 0x2d, 0x64,
271                 0x61, 0x1e, 0xee, 0xb6, 0x9a, 0xcd, 0xc0, 0x55,
272                 0x95, 0x7c, 0x13, 0x9e, 0x8b, 0x19, 0x0c, 0x7a,
273                 0x06, 0x95, 0x5f, 0x2c, 0x79, 0x7c, 0x27, 0x78,
274                 0xde, 0x94, 0x03, 0x96, 0xa5, 0x01, 0xf4, 0x0e,
275                 0x91, 0x39, 0x6a, 0xcf, 0x8d, 0x7e, 0x45, 0xeb,
276                 0xdb, 0xb5, 0x3b, 0xbf, 0x8c, 0x97, 0x52, 0x30,
277                 0xd2, 0xf0, 0xff, 0x91, 0x06, 0xc7, 0x61, 0x19,
278                 0xae, 0x49, 0x8e, 0x7f, 0xbc, 0x03, 0xd9, 0x0f,
279                 0x8e, 0x4c, 0x51, 0x62, 0x7a, 0xed, 0x5c, 0x8d,
280                 0x42, 0x63, 0xd5, 0xd2, 0xb9, 0x78, 0x87, 0x3a,
281                 0x0d, 0xe5, 0x96, 0xee, 0x6d, 0xc7, 0xf7, 0xc2,
282                 0x9e, 0x37, 0xee, 0xe8, 0xb3, 0x4c, 0x90, 0xdd,
283                 0x1c, 0xf6, 0xa9, 0xdd, 0xb2, 0x2b, 0x4c, 0xbd,
284                 0x08, 0x6b, 0x14, 0xb3, 0x5d, 0xe9, 0x3d, 0xa2,
285                 0xd5, 0xcb, 0x18, 0x06, 0x69, 0x8c, 0xbd, 0x7b,
286                 0xbb, 0x67, 0xbf, 0xe3, 0xd3, 0x1f, 0xd2, 0xd1,
287                 0xdb, 0xd2, 0xa1, 0xe0, 0x58, 0xa3, 0xeb, 0x99,
288                 0xd7, 0xe5, 0x1f, 0x1a, 0x93, 0x8e, 0xed, 0x5e,
289                 0x1c, 0x1d, 0xe2, 0x3a, 0x6b, 0x43, 0x45, 0xd3,
290                 0x19, 0x14, 0x09, 0xf9, 0x2f, 0x39, 0xb3, 0x67,
291                 0x0d, 0x8d, 0xbf, 0xb6, 0x35, 0xd8, 0xe6, 0xa3,
292                 0x69, 0x32, 0xd8, 0x10, 0x33, 0xd1, 0x44, 0x8d,
293                 0x63, 0xb4, 0x03, 0xdd, 0xf8, 0x8e, 0x12, 0x1b,
294                 0x6e, 0x81, 0x9a, 0xc3, 0x81, 0x22, 0x6c, 0x13,
295                 0x21, 0xe4, 0xb0, 0x86, 0x44, 0xf6, 0x72, 0x7c,
296                 0x36, 0x8c, 0x5a, 0x9f, 0x7a, 0x4b, 0x3e, 0xe2 };
297 
298         u8 buf[sizeof(random)];
299         struct ppno_ws_s ws;
300 
301         memset(&ws, 0, sizeof(ws));
302 
303         /* initial seed */
304         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
305                    &ws, NULL, 0, seed, sizeof(seed));
306 
307         /* check working states V and C */
308         if (memcmp(ws.V, V0, sizeof(V0)) != 0
309             || memcmp(ws.C, C0, sizeof(C0)) != 0) {
310                 pr_err("The prng self test state test "
311                        "for the SHA-512 mode failed\n");
312                 prng_errorflag = PRNG_SELFTEST_FAILED;
313                 return -EIO;
314         }
315 
316         /* generate random bytes */
317         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
318                    &ws, buf, sizeof(buf), NULL, 0);
319         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
320                    &ws, buf, sizeof(buf), NULL, 0);
321 
322         /* check against expected data */
323         if (memcmp(buf, random, sizeof(random)) != 0) {
324                 pr_err("The prng self test data test "
325                        "for the SHA-512 mode failed\n");
326                 prng_errorflag = PRNG_SELFTEST_FAILED;
327                 return -EIO;
328         }
329 
330         return 0;
331 }
332 
333 
334 static int __init prng_sha512_instantiate(void)
335 {
336         int ret, datalen;
337         u8 seed[64];
338 
339         pr_debug("prng runs in SHA-512 mode "
340                  "with chunksize=%d and reseed_limit=%u\n",
341                  prng_chunk_size, prng_reseed_limit);
342 
343         /* memory allocation, prng_data struct init, mutex init */
344         datalen = sizeof(struct prng_data_s) + prng_chunk_size;
345         if (fips_enabled)
346                 datalen += prng_chunk_size;
347         prng_data = kzalloc(datalen, GFP_KERNEL);
348         if (!prng_data) {
349                 prng_errorflag = PRNG_INSTANTIATE_FAILED;
350                 return -ENOMEM;
351         }
352         mutex_init(&prng_data->mutex);
353         prng_data->buf = ((u8 *)prng_data) + sizeof(struct prng_data_s);
354 
355         /* selftest */
356         ret = prng_sha512_selftest();
357         if (ret)
358                 goto outfree;
359 
360         /* generate initial seed bytestring, first 48 bytes of entropy */
361         ret = generate_entropy(seed, 48);
362         if (ret != 48)
363                 goto outfree;
364         /* followed by 16 bytes of unique nonce */
365         get_tod_clock_ext(seed + 48);
366 
367         /* initial seed of the ppno drng */
368         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
369                    &prng_data->ppnows, NULL, 0, seed, sizeof(seed));
370 
371         /* if fips mode is enabled, generate a first block of random
372            bytes for the FIPS 140-2 Conditional Self Test */
373         if (fips_enabled) {
374                 prng_data->prev = prng_data->buf + prng_chunk_size;
375                 cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
376                            &prng_data->ppnows,
377                            prng_data->prev, prng_chunk_size, NULL, 0);
378         }
379 
380         return 0;
381 
382 outfree:
383         kfree(prng_data);
384         return ret;
385 }
386 
387 
388 static void prng_sha512_deinstantiate(void)
389 {
390         pr_debug("The prng module stopped after running in SHA-512 mode\n");
391         kzfree(prng_data);
392 }
393 
394 
395 static int prng_sha512_reseed(void)
396 {
397         int ret;
398         u8 seed[32];
399 
400         /* generate 32 bytes of fresh entropy */
401         ret = generate_entropy(seed, sizeof(seed));
402         if (ret != sizeof(seed))
403                 return ret;
404 
405         /* do a reseed of the ppno drng with this bytestring */
406         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
407                    &prng_data->ppnows, NULL, 0, seed, sizeof(seed));
408 
409         return 0;
410 }
411 
412 
413 static int prng_sha512_generate(u8 *buf, size_t nbytes)
414 {
415         int ret;
416 
417         /* reseed needed ? */
418         if (prng_data->ppnows.reseed_counter > prng_reseed_limit) {
419                 ret = prng_sha512_reseed();
420                 if (ret)
421                         return ret;
422         }
423 
424         /* PPNO generate */
425         cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
426                    &prng_data->ppnows, buf, nbytes, NULL, 0);
427 
428         /* FIPS 140-2 Conditional Self Test */
429         if (fips_enabled) {
430                 if (!memcmp(prng_data->prev, buf, nbytes)) {
431                         prng_errorflag = PRNG_GEN_FAILED;
432                         return -EILSEQ;
433                 }
434                 memcpy(prng_data->prev, buf, nbytes);
435         }
436 
437         return nbytes;
438 }
439 
440 
441 /*** file io functions ***/
442 
443 static int prng_open(struct inode *inode, struct file *file)
444 {
445         return nonseekable_open(inode, file);
446 }
447 
448 
449 static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
450                               size_t nbytes, loff_t *ppos)
451 {
452         int chunk, n, ret = 0;
453 
454         /* lock prng_data struct */
455         if (mutex_lock_interruptible(&prng_data->mutex))
456                 return -ERESTARTSYS;
457 
458         while (nbytes) {
459                 if (need_resched()) {
460                         if (signal_pending(current)) {
461                                 if (ret == 0)
462                                         ret = -ERESTARTSYS;
463                                 break;
464                         }
465                         /* give mutex free before calling schedule() */
466                         mutex_unlock(&prng_data->mutex);
467                         schedule();
468                         /* occopy mutex again */
469                         if (mutex_lock_interruptible(&prng_data->mutex)) {
470                                 if (ret == 0)
471                                         ret = -ERESTARTSYS;
472                                 return ret;
473                         }
474                 }
475 
476                 /*
477                  * we lose some random bytes if an attacker issues
478                  * reads < 8 bytes, but we don't care
479                  */
480                 chunk = min_t(int, nbytes, prng_chunk_size);
481 
482                 /* PRNG only likes multiples of 8 bytes */
483                 n = (chunk + 7) & -8;
484 
485                 if (prng_data->prngws.reseed_counter > prng_reseed_limit)
486                         prng_tdes_seed(8);
487 
488                 /* if the CPU supports PRNG stckf is present too */
489                 *((unsigned long long *)prng_data->buf) = get_tod_clock_fast();
490 
491                 /*
492                  * Beside the STCKF the input for the TDES-EDE is the output
493                  * of the last operation. We differ here from X9.17 since we
494                  * only store one timestamp into the buffer. Padding the whole
495                  * buffer with timestamps does not improve security, since
496                  * successive stckf have nearly constant offsets.
497                  * If an attacker knows the first timestamp it would be
498                  * trivial to guess the additional values. One timestamp
499                  * is therefore enough and still guarantees unique input values.
500                  *
501                  * Note: you can still get strict X9.17 conformity by setting
502                  * prng_chunk_size to 8 bytes.
503                  */
504                 cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
505                           prng_data->buf, prng_data->buf, n);
506 
507                 prng_data->prngws.byte_counter += n;
508                 prng_data->prngws.reseed_counter += n;
509 
510                 if (copy_to_user(ubuf, prng_data->buf, chunk)) {
511                         ret = -EFAULT;
512                         break;
513                 }
514 
515                 nbytes -= chunk;
516                 ret += chunk;
517                 ubuf += chunk;
518         }
519 
520         /* unlock prng_data struct */
521         mutex_unlock(&prng_data->mutex);
522 
523         return ret;
524 }
525 
526 
527 static ssize_t prng_sha512_read(struct file *file, char __user *ubuf,
528                                 size_t nbytes, loff_t *ppos)
529 {
530         int n, ret = 0;
531         u8 *p;
532 
533         /* if errorflag is set do nothing and return 'broken pipe' */
534         if (prng_errorflag)
535                 return -EPIPE;
536 
537         /* lock prng_data struct */
538         if (mutex_lock_interruptible(&prng_data->mutex))
539                 return -ERESTARTSYS;
540 
541         while (nbytes) {
542                 if (need_resched()) {
543                         if (signal_pending(current)) {
544                                 if (ret == 0)
545                                         ret = -ERESTARTSYS;
546                                 break;
547                         }
548                         /* give mutex free before calling schedule() */
549                         mutex_unlock(&prng_data->mutex);
550                         schedule();
551                         /* occopy mutex again */
552                         if (mutex_lock_interruptible(&prng_data->mutex)) {
553                                 if (ret == 0)
554                                         ret = -ERESTARTSYS;
555                                 return ret;
556                         }
557                 }
558                 if (prng_data->rest) {
559                         /* push left over random bytes from the previous read */
560                         p = prng_data->buf + prng_chunk_size - prng_data->rest;
561                         n = (nbytes < prng_data->rest) ?
562                                 nbytes : prng_data->rest;
563                         prng_data->rest -= n;
564                 } else {
565                         /* generate one chunk of random bytes into read buf */
566                         p = prng_data->buf;
567                         n = prng_sha512_generate(p, prng_chunk_size);
568                         if (n < 0) {
569                                 ret = n;
570                                 break;
571                         }
572                         if (nbytes < prng_chunk_size) {
573                                 n = nbytes;
574                                 prng_data->rest = prng_chunk_size - n;
575                         } else {
576                                 n = prng_chunk_size;
577                                 prng_data->rest = 0;
578                         }
579                 }
580                 if (copy_to_user(ubuf, p, n)) {
581                         ret = -EFAULT;
582                         break;
583                 }
584                 ubuf += n;
585                 nbytes -= n;
586                 ret += n;
587         }
588 
589         /* unlock prng_data struct */
590         mutex_unlock(&prng_data->mutex);
591 
592         return ret;
593 }
594 
595 
596 /*** sysfs stuff ***/
597 
598 static const struct file_operations prng_sha512_fops = {
599         .owner          = THIS_MODULE,
600         .open           = &prng_open,
601         .release        = NULL,
602         .read           = &prng_sha512_read,
603         .llseek         = noop_llseek,
604 };
605 static const struct file_operations prng_tdes_fops = {
606         .owner          = THIS_MODULE,
607         .open           = &prng_open,
608         .release        = NULL,
609         .read           = &prng_tdes_read,
610         .llseek         = noop_llseek,
611 };
612 
613 static struct miscdevice prng_sha512_dev = {
614         .name   = "prandom",
615         .minor  = MISC_DYNAMIC_MINOR,
616         .mode   = 0644,
617         .fops   = &prng_sha512_fops,
618 };
619 static struct miscdevice prng_tdes_dev = {
620         .name   = "prandom",
621         .minor  = MISC_DYNAMIC_MINOR,
622         .mode   = 0644,
623         .fops   = &prng_tdes_fops,
624 };
625 
626 
627 /* chunksize attribute (ro) */
628 static ssize_t prng_chunksize_show(struct device *dev,
629                                    struct device_attribute *attr,
630                                    char *buf)
631 {
632         return snprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size);
633 }
634 static DEVICE_ATTR(chunksize, 0444, prng_chunksize_show, NULL);
635 
636 /* counter attribute (ro) */
637 static ssize_t prng_counter_show(struct device *dev,
638                                  struct device_attribute *attr,
639                                  char *buf)
640 {
641         u64 counter;
642 
643         if (mutex_lock_interruptible(&prng_data->mutex))
644                 return -ERESTARTSYS;
645         if (prng_mode == PRNG_MODE_SHA512)
646                 counter = prng_data->ppnows.stream_bytes;
647         else
648                 counter = prng_data->prngws.byte_counter;
649         mutex_unlock(&prng_data->mutex);
650 
651         return snprintf(buf, PAGE_SIZE, "%llu\n", counter);
652 }
653 static DEVICE_ATTR(byte_counter, 0444, prng_counter_show, NULL);
654 
655 /* errorflag attribute (ro) */
656 static ssize_t prng_errorflag_show(struct device *dev,
657                                    struct device_attribute *attr,
658                                    char *buf)
659 {
660         return snprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag);
661 }
662 static DEVICE_ATTR(errorflag, 0444, prng_errorflag_show, NULL);
663 
664 /* mode attribute (ro) */
665 static ssize_t prng_mode_show(struct device *dev,
666                               struct device_attribute *attr,
667                               char *buf)
668 {
669         if (prng_mode == PRNG_MODE_TDES)
670                 return snprintf(buf, PAGE_SIZE, "TDES\n");
671         else
672                 return snprintf(buf, PAGE_SIZE, "SHA512\n");
673 }
674 static DEVICE_ATTR(mode, 0444, prng_mode_show, NULL);
675 
676 /* reseed attribute (w) */
677 static ssize_t prng_reseed_store(struct device *dev,
678                                  struct device_attribute *attr,
679                                  const char *buf, size_t count)
680 {
681         if (mutex_lock_interruptible(&prng_data->mutex))
682                 return -ERESTARTSYS;
683         prng_sha512_reseed();
684         mutex_unlock(&prng_data->mutex);
685 
686         return count;
687 }
688 static DEVICE_ATTR(reseed, 0200, NULL, prng_reseed_store);
689 
690 /* reseed limit attribute (rw) */
691 static ssize_t prng_reseed_limit_show(struct device *dev,
692                                       struct device_attribute *attr,
693                                       char *buf)
694 {
695         return snprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit);
696 }
697 static ssize_t prng_reseed_limit_store(struct device *dev,
698                                        struct device_attribute *attr,
699                                        const char *buf, size_t count)
700 {
701         unsigned limit;
702 
703         if (sscanf(buf, "%u\n", &limit) != 1)
704                 return -EINVAL;
705 
706         if (prng_mode == PRNG_MODE_SHA512) {
707                 if (limit < PRNG_RESEED_LIMIT_SHA512_LOWER)
708                         return -EINVAL;
709         } else {
710                 if (limit < PRNG_RESEED_LIMIT_TDES_LOWER)
711                         return -EINVAL;
712         }
713 
714         prng_reseed_limit = limit;
715 
716         return count;
717 }
718 static DEVICE_ATTR(reseed_limit, 0644,
719                    prng_reseed_limit_show, prng_reseed_limit_store);
720 
721 /* strength attribute (ro) */
722 static ssize_t prng_strength_show(struct device *dev,
723                                   struct device_attribute *attr,
724                                   char *buf)
725 {
726         return snprintf(buf, PAGE_SIZE, "256\n");
727 }
728 static DEVICE_ATTR(strength, 0444, prng_strength_show, NULL);
729 
730 static struct attribute *prng_sha512_dev_attrs[] = {
731         &dev_attr_errorflag.attr,
732         &dev_attr_chunksize.attr,
733         &dev_attr_byte_counter.attr,
734         &dev_attr_mode.attr,
735         &dev_attr_reseed.attr,
736         &dev_attr_reseed_limit.attr,
737         &dev_attr_strength.attr,
738         NULL
739 };
740 static struct attribute *prng_tdes_dev_attrs[] = {
741         &dev_attr_chunksize.attr,
742         &dev_attr_byte_counter.attr,
743         &dev_attr_mode.attr,
744         NULL
745 };
746 
747 static struct attribute_group prng_sha512_dev_attr_group = {
748         .attrs = prng_sha512_dev_attrs
749 };
750 static struct attribute_group prng_tdes_dev_attr_group = {
751         .attrs = prng_tdes_dev_attrs
752 };
753 
754 
755 /*** module init and exit ***/
756 
757 static int __init prng_init(void)
758 {
759         int ret;
760 
761         /* check if the CPU has a PRNG */
762         if (!cpacf_query_func(CPACF_KMC, CPACF_KMC_PRNG))
763                 return -EOPNOTSUPP;
764 
765         /* choose prng mode */
766         if (prng_mode != PRNG_MODE_TDES) {
767                 /* check for MSA5 support for PPNO operations */
768                 if (!cpacf_query_func(CPACF_PPNO, CPACF_PPNO_SHA512_DRNG_GEN)) {
769                         if (prng_mode == PRNG_MODE_SHA512) {
770                                 pr_err("The prng module cannot "
771                                        "start in SHA-512 mode\n");
772                                 return -EOPNOTSUPP;
773                         }
774                         prng_mode = PRNG_MODE_TDES;
775                 } else
776                         prng_mode = PRNG_MODE_SHA512;
777         }
778 
779         if (prng_mode == PRNG_MODE_SHA512) {
780 
781                 /* SHA512 mode */
782 
783                 if (prng_chunk_size < PRNG_CHUNKSIZE_SHA512_MIN
784                     || prng_chunk_size > PRNG_CHUNKSIZE_SHA512_MAX)
785                         return -EINVAL;
786                 prng_chunk_size = (prng_chunk_size + 0x3f) & ~0x3f;
787 
788                 if (prng_reseed_limit == 0)
789                         prng_reseed_limit = PRNG_RESEED_LIMIT_SHA512;
790                 else if (prng_reseed_limit < PRNG_RESEED_LIMIT_SHA512_LOWER)
791                         return -EINVAL;
792 
793                 ret = prng_sha512_instantiate();
794                 if (ret)
795                         goto out;
796 
797                 ret = misc_register(&prng_sha512_dev);
798                 if (ret) {
799                         prng_sha512_deinstantiate();
800                         goto out;
801                 }
802                 ret = sysfs_create_group(&prng_sha512_dev.this_device->kobj,
803                                          &prng_sha512_dev_attr_group);
804                 if (ret) {
805                         misc_deregister(&prng_sha512_dev);
806                         prng_sha512_deinstantiate();
807                         goto out;
808                 }
809 
810         } else {
811 
812                 /* TDES mode */
813 
814                 if (prng_chunk_size < PRNG_CHUNKSIZE_TDES_MIN
815                     || prng_chunk_size > PRNG_CHUNKSIZE_TDES_MAX)
816                         return -EINVAL;
817                 prng_chunk_size = (prng_chunk_size + 0x07) & ~0x07;
818 
819                 if (prng_reseed_limit == 0)
820                         prng_reseed_limit = PRNG_RESEED_LIMIT_TDES;
821                 else if (prng_reseed_limit < PRNG_RESEED_LIMIT_TDES_LOWER)
822                         return -EINVAL;
823 
824                 ret = prng_tdes_instantiate();
825                 if (ret)
826                         goto out;
827 
828                 ret = misc_register(&prng_tdes_dev);
829                 if (ret) {
830                         prng_tdes_deinstantiate();
831                         goto out;
832                 }
833                 ret = sysfs_create_group(&prng_tdes_dev.this_device->kobj,
834                                          &prng_tdes_dev_attr_group);
835                 if (ret) {
836                         misc_deregister(&prng_tdes_dev);
837                         prng_tdes_deinstantiate();
838                         goto out;
839                 }
840 
841         }
842 
843 out:
844         return ret;
845 }
846 
847 
848 static void __exit prng_exit(void)
849 {
850         if (prng_mode == PRNG_MODE_SHA512) {
851                 sysfs_remove_group(&prng_sha512_dev.this_device->kobj,
852                                    &prng_sha512_dev_attr_group);
853                 misc_deregister(&prng_sha512_dev);
854                 prng_sha512_deinstantiate();
855         } else {
856                 sysfs_remove_group(&prng_tdes_dev.this_device->kobj,
857                                    &prng_tdes_dev_attr_group);
858                 misc_deregister(&prng_tdes_dev);
859                 prng_tdes_deinstantiate();
860         }
861 }
862 
863 module_cpu_feature_match(MSA, prng_init);
864 module_exit(prng_exit);
865 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp