prng.c (889fac6d67d46a5e781c08fb26fec9016db1c307) | prng.c (c7d4d259b7477866376435155eb0ccdaee880677) |
---|---|
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 unchanged lines hidden (view full) --- 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 <asm/uaccess.h> 25#include <asm/timex.h> | 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 unchanged lines hidden (view full) --- 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 <asm/uaccess.h> 25#include <asm/timex.h> |
26#include <asm/cpacf.h> |
|
26 | 27 |
27#include "crypt_s390.h" 28 | |
29MODULE_LICENSE("GPL"); 30MODULE_AUTHOR("IBM Corporation"); 31MODULE_DESCRIPTION("s390 PRNG interface"); 32 33 34#define PRNG_MODE_AUTO 0 35#define PRNG_MODE_TDES 1 36#define PRNG_MODE_SHA512 2 --- 94 unchanged lines hidden (view full) --- 131 *p ^= get_tod_clock_fast(); 132 } 133 n = (nbytes < sizeof(hash)) ? nbytes : sizeof(hash); 134 if (n < sizeof(hash)) 135 h = hash; 136 else 137 h = ebuf; 138 /* generate sha256 from this page */ | 28MODULE_LICENSE("GPL"); 29MODULE_AUTHOR("IBM Corporation"); 30MODULE_DESCRIPTION("s390 PRNG interface"); 31 32 33#define PRNG_MODE_AUTO 0 34#define PRNG_MODE_TDES 1 35#define PRNG_MODE_SHA512 2 --- 94 unchanged lines hidden (view full) --- 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 */ |
139 if (crypt_s390_kimd(KIMD_SHA_256, h, 140 pg, PAGE_SIZE) != PAGE_SIZE) { | 138 if (cpacf_kimd(CPACF_KIMD_SHA_256, h, 139 pg, PAGE_SIZE) != PAGE_SIZE) { |
141 prng_errorflag = PRNG_GEN_ENTROPY_FAILED; 142 ret = -EIO; 143 goto out; 144 } 145 if (n < sizeof(hash)) 146 memcpy(ebuf, hash, n); 147 ret += n; 148 ebuf += n; --- 10 unchanged lines hidden (view full) --- 159 160static void prng_tdes_add_entropy(void) 161{ 162 __u64 entropy[4]; 163 unsigned int i; 164 int ret; 165 166 for (i = 0; i < 16; i++) { | 140 prng_errorflag = PRNG_GEN_ENTROPY_FAILED; 141 ret = -EIO; 142 goto out; 143 } 144 if (n < sizeof(hash)) 145 memcpy(ebuf, hash, n); 146 ret += n; 147 ebuf += n; --- 10 unchanged lines hidden (view full) --- 158 159static void prng_tdes_add_entropy(void) 160{ 161 __u64 entropy[4]; 162 unsigned int i; 163 int ret; 164 165 for (i = 0; i < 16; i++) { |
167 ret = crypt_s390_kmc(KMC_PRNG, prng_data->prngws.parm_block, 168 (char *)entropy, (char *)entropy, 169 sizeof(entropy)); | 166 ret = cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block, 167 (char *)entropy, (char *)entropy, 168 sizeof(entropy)); |
170 BUG_ON(ret < 0 || ret != sizeof(entropy)); 171 memcpy(prng_data->prngws.parm_block, entropy, sizeof(entropy)); 172 } 173} 174 175 176static void prng_tdes_seed(int nbytes) 177{ --- 128 unchanged lines hidden (view full) --- 306 307 int ret = 0; 308 u8 buf[sizeof(random)]; 309 struct ppno_ws_s ws; 310 311 memset(&ws, 0, sizeof(ws)); 312 313 /* initial seed */ | 169 BUG_ON(ret < 0 || ret != sizeof(entropy)); 170 memcpy(prng_data->prngws.parm_block, entropy, sizeof(entropy)); 171 } 172} 173 174 175static void prng_tdes_seed(int nbytes) 176{ --- 128 unchanged lines hidden (view full) --- 305 306 int ret = 0; 307 u8 buf[sizeof(random)]; 308 struct ppno_ws_s ws; 309 310 memset(&ws, 0, sizeof(ws)); 311 312 /* initial seed */ |
314 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_SEED, 315 &ws, NULL, 0, 316 seed, sizeof(seed)); | 313 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, &ws, NULL, 0, 314 seed, sizeof(seed)); |
317 if (ret < 0) { 318 pr_err("The prng self test seed operation for the " 319 "SHA-512 mode failed with rc=%d\n", ret); 320 prng_errorflag = PRNG_SELFTEST_FAILED; 321 return -EIO; 322 } 323 324 /* check working states V and C */ 325 if (memcmp(ws.V, V0, sizeof(V0)) != 0 326 || memcmp(ws.C, C0, sizeof(C0)) != 0) { 327 pr_err("The prng self test state test " 328 "for the SHA-512 mode failed\n"); 329 prng_errorflag = PRNG_SELFTEST_FAILED; 330 return -EIO; 331 } 332 333 /* generate random bytes */ | 315 if (ret < 0) { 316 pr_err("The prng self test seed operation for the " 317 "SHA-512 mode failed with rc=%d\n", ret); 318 prng_errorflag = PRNG_SELFTEST_FAILED; 319 return -EIO; 320 } 321 322 /* check working states V and C */ 323 if (memcmp(ws.V, V0, sizeof(V0)) != 0 324 || memcmp(ws.C, C0, sizeof(C0)) != 0) { 325 pr_err("The prng self test state test " 326 "for the SHA-512 mode failed\n"); 327 prng_errorflag = PRNG_SELFTEST_FAILED; 328 return -EIO; 329 } 330 331 /* generate random bytes */ |
334 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_GEN, 335 &ws, buf, sizeof(buf), 336 NULL, 0); | 332 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN, 333 &ws, buf, sizeof(buf), NULL, 0); |
337 if (ret < 0) { 338 pr_err("The prng self test generate operation for " 339 "the SHA-512 mode failed with rc=%d\n", ret); 340 prng_errorflag = PRNG_SELFTEST_FAILED; 341 return -EIO; 342 } | 334 if (ret < 0) { 335 pr_err("The prng self test generate operation for " 336 "the SHA-512 mode failed with rc=%d\n", ret); 337 prng_errorflag = PRNG_SELFTEST_FAILED; 338 return -EIO; 339 } |
343 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_GEN, 344 &ws, buf, sizeof(buf), 345 NULL, 0); | 340 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN, 341 &ws, buf, sizeof(buf), NULL, 0); |
346 if (ret < 0) { 347 pr_err("The prng self test generate operation for " 348 "the SHA-512 mode failed with rc=%d\n", ret); 349 prng_errorflag = PRNG_SELFTEST_FAILED; 350 return -EIO; 351 } 352 353 /* check against expected data */ --- 37 unchanged lines hidden (view full) --- 391 /* generate initial seed bytestring, first 48 bytes of entropy */ 392 ret = generate_entropy(seed, 48); 393 if (ret != 48) 394 goto outfree; 395 /* followed by 16 bytes of unique nonce */ 396 get_tod_clock_ext(seed + 48); 397 398 /* initial seed of the ppno drng */ | 342 if (ret < 0) { 343 pr_err("The prng self test generate operation for " 344 "the SHA-512 mode failed with rc=%d\n", ret); 345 prng_errorflag = PRNG_SELFTEST_FAILED; 346 return -EIO; 347 } 348 349 /* check against expected data */ --- 37 unchanged lines hidden (view full) --- 387 /* generate initial seed bytestring, first 48 bytes of entropy */ 388 ret = generate_entropy(seed, 48); 389 if (ret != 48) 390 goto outfree; 391 /* followed by 16 bytes of unique nonce */ 392 get_tod_clock_ext(seed + 48); 393 394 /* initial seed of the ppno drng */ |
399 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_SEED, 400 &prng_data->ppnows, NULL, 0, 401 seed, sizeof(seed)); | 395 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, 396 &prng_data->ppnows, NULL, 0, seed, sizeof(seed)); |
402 if (ret < 0) { 403 prng_errorflag = PRNG_SEED_FAILED; 404 ret = -EIO; 405 goto outfree; 406 } 407 408 /* if fips mode is enabled, generate a first block of random 409 bytes for the FIPS 140-2 Conditional Self Test */ 410 if (fips_enabled) { 411 prng_data->prev = prng_data->buf + prng_chunk_size; | 397 if (ret < 0) { 398 prng_errorflag = PRNG_SEED_FAILED; 399 ret = -EIO; 400 goto outfree; 401 } 402 403 /* if fips mode is enabled, generate a first block of random 404 bytes for the FIPS 140-2 Conditional Self Test */ 405 if (fips_enabled) { 406 prng_data->prev = prng_data->buf + prng_chunk_size; |
412 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_GEN, 413 &prng_data->ppnows, 414 prng_data->prev, 415 prng_chunk_size, 416 NULL, 0); | 407 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN, 408 &prng_data->ppnows, 409 prng_data->prev, prng_chunk_size, NULL, 0); |
417 if (ret < 0 || ret != prng_chunk_size) { 418 prng_errorflag = PRNG_GEN_FAILED; 419 ret = -EIO; 420 goto outfree; 421 } 422 } 423 424 return 0; --- 17 unchanged lines hidden (view full) --- 442 u8 seed[32]; 443 444 /* generate 32 bytes of fresh entropy */ 445 ret = generate_entropy(seed, sizeof(seed)); 446 if (ret != sizeof(seed)) 447 return ret; 448 449 /* do a reseed of the ppno drng with this bytestring */ | 410 if (ret < 0 || ret != prng_chunk_size) { 411 prng_errorflag = PRNG_GEN_FAILED; 412 ret = -EIO; 413 goto outfree; 414 } 415 } 416 417 return 0; --- 17 unchanged lines hidden (view full) --- 435 u8 seed[32]; 436 437 /* generate 32 bytes of fresh entropy */ 438 ret = generate_entropy(seed, sizeof(seed)); 439 if (ret != sizeof(seed)) 440 return ret; 441 442 /* do a reseed of the ppno drng with this bytestring */ |
450 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_SEED, 451 &prng_data->ppnows, NULL, 0, 452 seed, sizeof(seed)); | 443 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, 444 &prng_data->ppnows, NULL, 0, seed, sizeof(seed)); |
453 if (ret) { 454 prng_errorflag = PRNG_RESEED_FAILED; 455 return -EIO; 456 } 457 458 return 0; 459} 460 --- 5 unchanged lines hidden (view full) --- 466 /* reseed needed ? */ 467 if (prng_data->ppnows.reseed_counter > prng_reseed_limit) { 468 ret = prng_sha512_reseed(); 469 if (ret) 470 return ret; 471 } 472 473 /* PPNO generate */ | 445 if (ret) { 446 prng_errorflag = PRNG_RESEED_FAILED; 447 return -EIO; 448 } 449 450 return 0; 451} 452 --- 5 unchanged lines hidden (view full) --- 458 /* reseed needed ? */ 459 if (prng_data->ppnows.reseed_counter > prng_reseed_limit) { 460 ret = prng_sha512_reseed(); 461 if (ret) 462 return ret; 463 } 464 465 /* PPNO generate */ |
474 ret = crypt_s390_ppno(PPNO_SHA512_DRNG_GEN, 475 &prng_data->ppnows, buf, nbytes, 476 NULL, 0); | 466 ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN, 467 &prng_data->ppnows, buf, nbytes, NULL, 0); |
477 if (ret < 0 || ret != nbytes) { 478 prng_errorflag = PRNG_GEN_FAILED; 479 return -EIO; 480 } 481 482 /* FIPS 140-2 Conditional Self Test */ 483 if (fips_enabled) { 484 if (!memcmp(prng_data->prev, buf, nbytes)) { --- 65 unchanged lines hidden (view full) --- 550 * successive stckf have nearly constant offsets. 551 * If an attacker knows the first timestamp it would be 552 * trivial to guess the additional values. One timestamp 553 * is therefore enough and still guarantees unique input values. 554 * 555 * Note: you can still get strict X9.17 conformity by setting 556 * prng_chunk_size to 8 bytes. 557 */ | 468 if (ret < 0 || ret != nbytes) { 469 prng_errorflag = PRNG_GEN_FAILED; 470 return -EIO; 471 } 472 473 /* FIPS 140-2 Conditional Self Test */ 474 if (fips_enabled) { 475 if (!memcmp(prng_data->prev, buf, nbytes)) { --- 65 unchanged lines hidden (view full) --- 541 * successive stckf have nearly constant offsets. 542 * If an attacker knows the first timestamp it would be 543 * trivial to guess the additional values. One timestamp 544 * is therefore enough and still guarantees unique input values. 545 * 546 * Note: you can still get strict X9.17 conformity by setting 547 * prng_chunk_size to 8 bytes. 548 */ |
558 tmp = crypt_s390_kmc(KMC_PRNG, prng_data->prngws.parm_block, 559 prng_data->buf, prng_data->buf, n); | 549 tmp = cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block, 550 prng_data->buf, prng_data->buf, n); |
560 if (tmp < 0 || tmp != n) { 561 ret = -EIO; 562 break; 563 } 564 565 prng_data->prngws.byte_counter += n; 566 prng_data->prngws.reseed_counter += n; 567 --- 242 unchanged lines hidden (view full) --- 810 811/*** module init and exit ***/ 812 813static int __init prng_init(void) 814{ 815 int ret; 816 817 /* check if the CPU has a PRNG */ | 551 if (tmp < 0 || tmp != n) { 552 ret = -EIO; 553 break; 554 } 555 556 prng_data->prngws.byte_counter += n; 557 prng_data->prngws.reseed_counter += n; 558 --- 242 unchanged lines hidden (view full) --- 801 802/*** module init and exit ***/ 803 804static int __init prng_init(void) 805{ 806 int ret; 807 808 /* check if the CPU has a PRNG */ |
818 if (!crypt_s390_func_available(KMC_PRNG, CRYPT_S390_MSA)) | 809 if (!cpacf_query(CPACF_KMC, CPACF_KMC_PRNG)) |
819 return -EOPNOTSUPP; 820 821 /* choose prng mode */ 822 if (prng_mode != PRNG_MODE_TDES) { 823 /* check for MSA5 support for PPNO operations */ | 810 return -EOPNOTSUPP; 811 812 /* choose prng mode */ 813 if (prng_mode != PRNG_MODE_TDES) { 814 /* check for MSA5 support for PPNO operations */ |
824 if (!crypt_s390_func_available(PPNO_SHA512_DRNG_GEN, 825 CRYPT_S390_MSA5)) { | 815 if (!cpacf_query(CPACF_PPNO, CPACF_PPNO_SHA512_DRNG_GEN)) { |
826 if (prng_mode == PRNG_MODE_SHA512) { 827 pr_err("The prng module cannot " 828 "start in SHA-512 mode\n"); 829 return -EOPNOTSUPP; 830 } 831 prng_mode = PRNG_MODE_TDES; 832 } else 833 prng_mode = PRNG_MODE_SHA512; --- 88 unchanged lines hidden --- | 816 if (prng_mode == PRNG_MODE_SHA512) { 817 pr_err("The prng module cannot " 818 "start in SHA-512 mode\n"); 819 return -EOPNOTSUPP; 820 } 821 prng_mode = PRNG_MODE_TDES; 822 } else 823 prng_mode = PRNG_MODE_SHA512; --- 88 unchanged lines hidden --- |