genrandom.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "os.h"
  10. #include <mp.h>
  11. #include <libsec.h>
  12. typedef struct State{
  13. QLock lock;
  14. int seeded;
  15. uint64_t seed;
  16. DES3state des3;
  17. } State;
  18. static State x917state;
  19. static void
  20. X917(uint8_t *rand, int nrand)
  21. {
  22. int i, m, n8;
  23. uint64_t I, x;
  24. /* 1. Compute intermediate value I = Ek(time). */
  25. I = nsec();
  26. triple_block_cipher(x917state.des3.expanded, (uint8_t*)&I, 0); /* two-key EDE */
  27. /* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */
  28. m = (nrand+7)/8;
  29. for(i=0; i<m; i++){
  30. x = I ^ x917state.seed;
  31. triple_block_cipher(x917state.des3.expanded, (uint8_t*)&x, 0);
  32. n8 = (nrand>8) ? 8 : nrand;
  33. memcpy(rand, (uint8_t*)&x, n8);
  34. rand += 8;
  35. nrand -= 8;
  36. x ^= I;
  37. triple_block_cipher(x917state.des3.expanded, (uint8_t*)&x, 0);
  38. x917state.seed = x;
  39. }
  40. }
  41. static void
  42. X917init(void)
  43. {
  44. int n;
  45. uint8_t mix[128];
  46. uint8_t key3[3][8];
  47. uint32_t *ulp;
  48. ulp = (uint32_t*)key3;
  49. for(n = 0; n < sizeof(key3)/sizeof(uint32_t); n++)
  50. ulp[n] = truerand();
  51. setupDES3state(&x917state.des3, key3, nil);
  52. X917(mix, sizeof mix);
  53. x917state.seeded = 1;
  54. }
  55. void
  56. genrandom(uint8_t *p, int n)
  57. {
  58. qlock(&x917state.lock);
  59. if(x917state.seeded == 0)
  60. X917init();
  61. X917(p, n);
  62. qunlock(&x917state.lock);
  63. }