MagickCore  7.0.3
random.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % RRRR AAA N N DDDD OOO M M %
6 % R R A A NN N D D O O MM MM %
7 % RRRR AAAAA N N N D D O O M M M %
8 % R R A A N NN D D O O M M %
9 % R R A A N N DDDD OOO M M %
10 % %
11 % %
12 % MagickCore Methods to Generate Random Numbers %
13 % %
14 % Software Design %
15 % Cristy %
16 % December 2001 %
17 % %
18 % %
19 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 % The generation of random numbers is too important to be left to chance.
36 % -- Tom Christiansen <tchrist@mox.perl.com>
37 %
38 %
39 */
40 
41 /*
42  Include declarations.
43 */
44 #if defined(__VMS)
45 #include <time.h>
46 #endif
47 #if defined(__MINGW32__)
48 #include <sys/time.h>
49 #endif
50 #include "MagickCore/studio.h"
51 #include "MagickCore/exception.h"
54 #include "MagickCore/memory_.h"
56 #include "MagickCore/semaphore.h"
57 #include "MagickCore/random_.h"
59 #include "MagickCore/resource_.h"
61 #include "MagickCore/string_.h"
62 #include "MagickCore/thread_.h"
64 #include "MagickCore/utility.h"
66 /*
67  Define declarations.
68 */
69 #define PseudoRandomHash SHA256Hash
70 #define RandomEntropyLevel 9
71 #define RandomFilename "reservoir.xdm"
72 #define RandomFiletype "random"
73 #define RandomProtocolMajorVersion 1
74 #define RandomProtocolMinorVersion 0
75 
76 /*
77  Typedef declarations.
78 */
80 {
83 
86  *reservoir;
87 
88  size_t
89  i;
90 
91  unsigned long
92  seed[4];
93 
94  double
96 
97  unsigned long
99 
100  unsigned short
103 
106 
107  ssize_t
109 
110  size_t
112 };
113 
114 /*
115  External declarations.
116 */
117 #if defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
118 #include <crt_externs.h>
119 #define environ (*_NSGetEnviron())
120 #endif
121 
122 #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
123 extern char
124  **environ;
125 #endif
126 
127 /*
128  Global declarations.
129 */
130 static SemaphoreInfo
132 
133 static unsigned long
134  secret_key = ~0UL;
135 
136 static MagickBooleanType
138 
139 /*
140  Forward declarations.
141 */
142 static StringInfo
144 
145 /*
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147 % %
148 % %
149 % %
150 % A c q u i r e R a n d o m I n f o %
151 % %
152 % %
153 % %
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 %
156 % AcquireRandomInfo() allocates the RandomInfo structure.
157 %
158 % The format of the AcquireRandomInfo method is:
159 %
160 % RandomInfo *AcquireRandomInfo(void)
161 %
162 */
164 {
165  const StringInfo
166  *digest;
167 
168  RandomInfo
169  *random_info;
170 
171  StringInfo
172  *entropy,
173  *key,
174  *nonce;
175 
176  random_info=(RandomInfo *) AcquireCriticalMemory(sizeof(*random_info));
177  (void) memset(random_info,0,sizeof(*random_info));
178  random_info->signature_info=AcquireSignatureInfo();
180  random_info->signature_info));
181  ResetStringInfo(random_info->nonce);
183  random_info->signature_info));
184  ResetStringInfo(random_info->reservoir);
185  random_info->normalize=1.0/(~0UL);
186  random_info->secret_key=secret_key;
189  random_info->semaphore=AcquireSemaphoreInfo();
190  random_info->timestamp=(ssize_t) time(0);
191  random_info->signature=MagickCoreSignature;
192  /*
193  Seed random nonce.
194  */
195  nonce=GenerateEntropicChaos(random_info);
196  if (nonce == (StringInfo *) NULL)
197  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
198  InitializeSignature(random_info->signature_info);
199  UpdateSignature(random_info->signature_info,nonce);
200  FinalizeSignature(random_info->signature_info);
202  random_info->signature_info)+1)/2);
203  SetStringInfo(nonce,GetSignatureDigest(random_info->signature_info));
204  SetStringInfo(random_info->nonce,nonce);
205  nonce=DestroyStringInfo(nonce);
206  /*
207  Seed random reservoir with entropic data.
208  */
209  entropy=GenerateEntropicChaos(random_info);
210  if (entropy == (StringInfo *) NULL)
211  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
212  UpdateSignature(random_info->signature_info,entropy);
213  FinalizeSignature(random_info->signature_info);
215  random_info->signature_info));
216  entropy=DestroyStringInfo(entropy);
217  /*
218  Seed pseudo random number generator.
219  */
220  if (random_info->secret_key == ~0UL)
221  {
222  key=GetRandomKey(random_info,sizeof(random_info->secret_key));
223  (void) memcpy(random_info->seed,GetStringInfoDatum(key),
224  GetStringInfoLength(key));
225  key=DestroyStringInfo(key);
226  }
227  else
228  {
230  *signature_info;
231 
232  signature_info=AcquireSignatureInfo();
233  key=AcquireStringInfo(sizeof(random_info->secret_key));
234  SetStringInfoDatum(key,(unsigned char *) &random_info->secret_key);
235  UpdateSignature(signature_info,key);
236  key=DestroyStringInfo(key);
237  FinalizeSignature(signature_info);
238  digest=GetSignatureDigest(signature_info);
239  (void) memcpy(random_info->seed,GetStringInfoDatum(digest),
240  MagickMin(GetSignatureDigestsize(signature_info),
241  sizeof(*random_info->seed)));
242  signature_info=DestroySignatureInfo(signature_info);
243  }
244  random_info->seed[1]=0x50a7f451UL;
245  random_info->seed[2]=0x5365417eUL;
246  random_info->seed[3]=0xc3a4171aUL;
247  return(random_info);
248 }
249 
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % %
253 % %
254 % %
255 + D e s t r o y R a n d o m I n f o %
256 % %
257 % %
258 % %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 % DestroyRandomInfo() deallocates memory associated with the random
262 % reservoir.
263 %
264 % The format of the DestroyRandomInfo method is:
265 %
266 % RandomInfo *DestroyRandomInfo(RandomInfo *random_info)
267 %
268 % A description of each parameter follows:
269 %
270 % o random_info: the random info.
271 %
272 */
274 {
275  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
276  assert(random_info != (RandomInfo *) NULL);
277  assert(random_info->signature == MagickCoreSignature);
278  LockSemaphoreInfo(random_info->semaphore);
279  if (random_info->reservoir != (StringInfo *) NULL)
280  random_info->reservoir=DestroyStringInfo(random_info->reservoir);
281  if (random_info->nonce != (StringInfo *) NULL)
282  random_info->nonce=DestroyStringInfo(random_info->nonce);
283  if (random_info->signature_info != (SignatureInfo *) NULL)
285  random_info->signature_info);
286  (void) memset(random_info->seed,0,sizeof(random_info->seed));
287  random_info->signature=(~MagickCoreSignature);
288  UnlockSemaphoreInfo(random_info->semaphore);
289  RelinquishSemaphoreInfo(&random_info->semaphore);
290  random_info=(RandomInfo *) RelinquishMagickMemory(random_info);
291  return(random_info);
292 }
293 
294 /*
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296 % %
297 % %
298 % %
299 + G e n e r a t e E n t r o p i c C h a o s %
300 % %
301 % %
302 % %
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304 %
305 % GenerateEntropicChaos() generate entropic chaos used to initialize the
306 % random reservoir.
307 %
308 % The format of the GenerateEntropicChaos method is:
309 %
310 % StringInfo *GenerateEntropicChaos(RandomInfo *random_info)
311 %
312 % A description of each parameter follows:
313 %
314 % o random_info: the random info.
315 %
316 */
317 
318 #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
319 static ssize_t ReadRandom(int file,unsigned char *source,size_t length)
320 {
321  register unsigned char
322  *q;
323 
324  ssize_t
325  offset,
326  count;
327 
328  offset=0;
329  for (q=source; length != 0; length-=count)
330  {
331  count=(ssize_t) read(file,q,length);
332  if (count <= 0)
333  {
334  count=0;
335  if (errno == EINTR)
336  continue;
337  return(-1);
338  }
339  q+=count;
340  offset+=count;
341  }
342  return(offset);
343 }
344 #endif
345 
347 {
348 #define MaxEntropyExtent 64
349 
351  tid;
352 
353  StringInfo
354  *chaos,
355  *entropy;
356 
357  size_t
358  nanoseconds,
359  seconds;
360 
361  ssize_t
362  pid;
363 
364  /*
365  Initialize random reservoir.
366  */
367  entropy=AcquireStringInfo(0);
368  LockSemaphoreInfo(random_info->semaphore);
369  chaos=AcquireStringInfo(sizeof(unsigned char *));
370  SetStringInfoDatum(chaos,(unsigned char *) &entropy);
371  ConcatenateStringInfo(entropy,chaos);
372  SetStringInfoDatum(chaos,(unsigned char *) entropy);
373  ConcatenateStringInfo(entropy,chaos);
374  pid=(ssize_t) getpid();
375  SetStringInfoLength(chaos,sizeof(pid));
376  SetStringInfoDatum(chaos,(unsigned char *) &pid);
377  ConcatenateStringInfo(entropy,chaos);
378  tid=GetMagickThreadId();
379  SetStringInfoLength(chaos,sizeof(tid));
380  SetStringInfoDatum(chaos,(unsigned char *) &tid);
381  ConcatenateStringInfo(entropy,chaos);
382 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
383  {
384  ssize_t
385  pages;
386 
387  pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
388  SetStringInfoLength(chaos,sizeof(pages));
389  SetStringInfoDatum(chaos,(unsigned char *) &pages);
390  ConcatenateStringInfo(entropy,chaos);
391  }
392 #endif
393 #if defined(MAGICKCORE_HAVE_GETRUSAGE) && defined(RUSAGE_SELF)
394  {
395  struct rusage
396  usage;
397 
398  if (getrusage(RUSAGE_SELF,&usage) == 0)
399  {
400  SetStringInfoLength(chaos,sizeof(usage));
401  SetStringInfoDatum(chaos,(unsigned char *) &usage);
402  }
403  }
404 #endif
405  seconds=time((time_t *) 0);
406  nanoseconds=0;
407 #if defined(MAGICKCORE_HAVE_GETTIMEOFDAY)
408  {
409  struct timeval
410  timer;
411 
412  if (gettimeofday(&timer,(struct timezone *) NULL) == 0)
413  {
414  seconds=timer.tv_sec;
415  nanoseconds=1000UL*timer.tv_usec;
416  }
417  }
418 #endif
419 #if defined(MAGICKCORE_HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME_HR)
420  {
421  struct timespec
422  timer;
423 
424  if (clock_gettime(CLOCK_REALTIME_HR,&timer) == 0)
425  {
426  seconds=timer.tv_sec;
427  nanoseconds=timer.tv_nsec;
428  }
429  }
430 #endif
431  SetStringInfoLength(chaos,sizeof(seconds));
432  SetStringInfoDatum(chaos,(unsigned char *) &seconds);
433  ConcatenateStringInfo(entropy,chaos);
434  SetStringInfoLength(chaos,sizeof(nanoseconds));
435  SetStringInfoDatum(chaos,(unsigned char *) &nanoseconds);
436  ConcatenateStringInfo(entropy,chaos);
437  nanoseconds=0;
438 #if defined(MAGICKCORE_HAVE_CLOCK)
439  nanoseconds=clock();
440 #endif
441 #if defined(MAGICKCORE_HAVE_TIMES)
442  {
443  struct tms
444  timer;
445 
446  (void) times(&timer);
447  nanoseconds=timer.tms_utime+timer.tms_stime;
448  }
449 #endif
450  SetStringInfoLength(chaos,sizeof(nanoseconds));
451  SetStringInfoDatum(chaos,(unsigned char *) &nanoseconds);
452  ConcatenateStringInfo(entropy,chaos);
453 #if defined(MAGICKCORE_HAVE_MKSTEMP)
454  {
455  char
456  path[MagickPathExtent];
457 
458  int
459  file;
460 
461  (void) strcpy(path,"XXXXXX");
462  file=mkstemp(path);
463  if (file != -1)
464  {
465 #if defined(MAGICKCORE_HAVE_FCHMOD)
466  (void) fchmod(file,0600);
467 #endif
468 #if defined(__OS2__)
469  setmode(file,O_BINARY);
470 #endif
471  (void) close(file);
472  }
473  (void) remove_utf8(path);
474  SetStringInfoLength(chaos,strlen(path));
475  SetStringInfoDatum(chaos,(unsigned char *) path);
476  ConcatenateStringInfo(entropy,chaos);
477  }
478 #endif
479 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
480  {
481  double
482  seconds;
483 
484  LARGE_INTEGER
485  nanoseconds;
486 
487  /*
488  Not crytographically strong but better than nothing.
489  */
490  seconds=NTElapsedTime()+NTUserTime();
491  SetStringInfoLength(chaos,sizeof(seconds));
492  SetStringInfoDatum(chaos,(unsigned char *) &seconds);
493  ConcatenateStringInfo(entropy,chaos);
494  if (QueryPerformanceCounter(&nanoseconds) != 0)
495  {
496  SetStringInfoLength(chaos,sizeof(nanoseconds));
497  SetStringInfoDatum(chaos,(unsigned char *) &nanoseconds);
498  ConcatenateStringInfo(entropy,chaos);
499  }
500  /*
501  Our best hope for true entropy.
502  */
504  (void) NTGatherRandomData(MaxEntropyExtent,GetStringInfoDatum(chaos));
505  ConcatenateStringInfo(entropy,chaos);
506  }
507 #else
508  {
509  char
510  *filename;
511 
512  int
513  file;
514 
515  ssize_t
516  count;
517 
518  StringInfo
519  *device;
520 
521  /*
522  Not crytographically strong but better than nothing.
523  */
524  if (environ != (char **) NULL)
525  {
526  register ssize_t
527  i;
528 
529  /*
530  Squeeze some entropy from the sometimes unpredicatble environment.
531  */
532  for (i=0; environ[i] != (char *) NULL; i++)
533  {
534  SetStringInfoLength(chaos,strlen(environ[i]));
535  SetStringInfoDatum(chaos,(unsigned char *) environ[i]);
536  ConcatenateStringInfo(entropy,chaos);
537  }
538  }
539  filename=AcquireString("/dev/urandom");
540  device=StringToStringInfo(filename);
541  device=DestroyStringInfo(device);
542  file=open_utf8(filename,O_RDONLY | O_BINARY,0);
543  filename=DestroyString(filename);
544  if (file != -1)
545  {
548  (void) close(file);
549  SetStringInfoLength(chaos,(size_t) count);
550  ConcatenateStringInfo(entropy,chaos);
551  }
553  {
554  /*
555  Our best hope for true entropy.
556  */
557  filename=AcquireString("/dev/random");
558  device=StringToStringInfo(filename);
559  device=DestroyStringInfo(device);
560  file=open_utf8(filename,O_RDONLY | O_BINARY,0);
561  filename=DestroyString(filename);
562  if (file == -1)
563  {
564  filename=AcquireString("/dev/srandom");
565  device=StringToStringInfo(filename);
566  device=DestroyStringInfo(device);
567  file=open_utf8(filename,O_RDONLY | O_BINARY,0);
568  }
569  if (file != -1)
570  {
573  (void) close(file);
574  SetStringInfoLength(chaos,(size_t) count);
575  ConcatenateStringInfo(entropy,chaos);
576  }
577  }
578  }
579 #endif
580  chaos=DestroyStringInfo(chaos);
581  UnlockSemaphoreInfo(random_info->semaphore);
582  return(entropy);
583 }
584 
585 /*
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 % %
588 % %
589 % %
590 % G e t P s e u d o R a n d o m V a l u e %
591 % %
592 % %
593 % %
594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 %
596 % GetPseudoRandomValue() return a non-negative double-precision floating-point
597 % value uniformly distributed over the interval [0.0, 1.0) with a 2 to the
598 % 128th-1 period.
599 %
600 % The format of the GetPseudoRandomValue method is:
601 %
602 % double GetPseudoRandomValue(RandomInfo *randon_info)
603 %
604 % A description of each parameter follows:
605 %
606 % o random_info: the random info.
607 %
608 */
610 {
611  register unsigned long
612  *seed;
613 
614  unsigned long
615  alpha;
616 
617  seed=random_info->seed;
618  do
619  {
620  alpha=(unsigned long) (seed[1] ^ (seed[1] << 11));
621  seed[1]=seed[2];
622  seed[2]=seed[3];
623  seed[3]=seed[0];
624  seed[0]=(seed[0] ^ (seed[0] >> 19)) ^ (alpha ^ (alpha >> 8));
625  } while (seed[0] == ~0UL);
626  return(random_info->normalize*seed[0]);
627 }
628 
629 /*
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631 % %
632 % %
633 % %
634 + G e t R a n d o m I n f o N o r m a l i z e %
635 % %
636 % %
637 % %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 %
640 % GetRandomInfoNormalize() returns the random normalize value.
641 %
642 % The format of the GetRandomInfoNormalize method is:
643 %
644 % double GetRandomInfoNormalize(const RandomInfo *random_info)
645 %
646 % A description of each parameter follows:
647 %
648 % o random_info: the random info.
649 %
650 */
652 {
653  assert(random_info != (const RandomInfo *) NULL);
654  return(random_info->normalize);
655 }
656 
657 /*
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659 % %
660 % %
661 % %
662 + G e t R a n d o m I n f o S e e d %
663 % %
664 % %
665 % %
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
667 %
668 % GetRandomInfoSeed() returns the random seed.
669 %
670 % The format of the GetRandomInfoSeed method is:
671 %
672 % unsigned long *GetRandomInfoSeed(RandomInfo *random_info)
673 %
674 % A description of each parameter follows:
675 %
676 % o random_info: the random info.
677 %
678 */
680 {
681  assert(random_info != (RandomInfo *) NULL);
682  return(random_info->seed);
683 }
684 
685 /*
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 % %
688 % %
689 % %
690 % G e t R a n d o m K e y %
691 % %
692 % %
693 % %
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 %
696 % GetRandomKey() gets a random key from the reservoir.
697 %
698 % The format of the GetRandomKey method is:
699 %
700 % StringInfo *GetRandomKey(RandomInfo *random_info,const size_t length)
701 %
702 % A description of each parameter follows:
703 %
704 % o random_info: the random info.
705 %
706 % o length: the key length.
707 %
708 */
710  const size_t length)
711 {
712  StringInfo
713  *key;
714 
715  assert(random_info != (RandomInfo *) NULL);
716  key=AcquireStringInfo(length);
717  SetRandomKey(random_info,length,GetStringInfoDatum(key));
718  return(key);
719 }
720 
721 /*
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 % %
724 % %
725 % %
726 % G e t R a n d o m S e c r e t K e y %
727 % %
728 % %
729 % %
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731 %
732 % GetRandomSecretKey() returns the random secet key.
733 %
734 % The format of the GetRandomSecretKey method is:
735 %
736 % unsigned long GetRandomSecretKey(const RandomInfo *random_info)
737 %
738 % A description of each parameter follows:
739 %
740 % o random_info: the random info.
741 */
743 {
744  return(random_info->secret_key);
745 }
746 
747 /*
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749 % %
750 % %
751 % %
752 % G e t R a n d o m V a l u e %
753 % %
754 % %
755 % %
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757 %
758 % GetRandomValue() return a non-negative double-precision floating-point
759 % value uniformly distributed over the interval [0.0, 1.0) with a 2 to the
760 % 128th-1 period (not cryptographically strong).
761 %
762 % The format of the GetRandomValue method is:
763 %
764 % double GetRandomValue(void)
765 %
766 */
768 {
769  unsigned long
770  key,
771  range;
772 
773  range=(~0UL);
774  do
775  {
776  SetRandomKey(random_info,sizeof(key),(unsigned char *) &key);
777  } while (key == range);
778  return((double) key/range);
779 }
780 
781 /*
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 % %
784 % %
785 % %
786 + R a n d o m C o m p o n e n t G e n e s i s %
787 % %
788 % %
789 % %
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 %
792 % RandomComponentGenesis() instantiates the random component.
793 %
794 % The format of the RandomComponentGenesis method is:
795 %
796 % MagickBooleanType RandomComponentGenesis(void)
797 %
798 */
800 {
801  if (random_semaphore == (SemaphoreInfo *) NULL)
803  return(MagickTrue);
804 }
805 
806 /*
807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808 % %
809 % %
810 % %
811 + R a n d o m C o m p o n e n t T e r m i n u s %
812 % %
813 % %
814 % %
815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 %
817 % RandomComponentTerminus() destroys the random component.
818 %
819 % The format of the RandomComponentTerminus method is:
820 %
821 % RandomComponentTerminus(void)
822 %
823 */
825 {
826  if (random_semaphore == (SemaphoreInfo *) NULL)
829 }
830 
831 /*
832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833 % %
834 % %
835 % %
836 % S e t R a n d o m K e y %
837 % %
838 % %
839 % %
840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 %
842 % SetRandomKey() sets a random key from the reservoir.
843 %
844 % The format of the SetRandomKey method is:
845 %
846 % void SetRandomKey(RandomInfo *random_info,const size_t length,
847 % unsigned char *key)
848 %
849 % A description of each parameter follows:
850 %
851 % o random_info: the random info.
852 %
853 % o length: the key length.
854 %
855 % o key: the key.
856 %
857 */
858 
859 static inline void IncrementRandomNonce(StringInfo *nonce)
860 {
861  register ssize_t
862  i;
863 
864  unsigned char
865  *datum;
866 
867  datum=GetStringInfoDatum(nonce);
868  for (i=(ssize_t) (GetStringInfoLength(nonce)-1); i != 0; i--)
869  {
870  datum[i]++;
871  if (datum[i] != 0)
872  return;
873  }
874  ThrowFatalException(RandomFatalError,"SequenceWrapError");
875 }
876 
878  unsigned char *key)
879 {
880  register size_t
881  i;
882 
883  register unsigned char
884  *p;
885 
887  *signature_info;
888 
889  unsigned char
890  *datum;
891 
892  assert(random_info != (RandomInfo *) NULL);
893  if (length == 0)
894  return;
895  LockSemaphoreInfo(random_info->semaphore);
896  signature_info=random_info->signature_info;
897  datum=GetStringInfoDatum(random_info->reservoir);
898  i=length;
899  for (p=key; (i != 0) && (random_info->i != 0); i--)
900  {
901  *p++=datum[random_info->i];
902  random_info->i++;
903  if (random_info->i == GetSignatureDigestsize(signature_info))
904  random_info->i=0;
905  }
906  while (i >= GetSignatureDigestsize(signature_info))
907  {
908  InitializeSignature(signature_info);
909  UpdateSignature(signature_info,random_info->nonce);
910  FinalizeSignature(signature_info);
911  IncrementRandomNonce(random_info->nonce);
912  (void) memcpy(p,GetStringInfoDatum(GetSignatureDigest(
913  signature_info)),GetSignatureDigestsize(signature_info));
914  p+=GetSignatureDigestsize(signature_info);
915  i-=GetSignatureDigestsize(signature_info);
916  }
917  if (i != 0)
918  {
919  InitializeSignature(signature_info);
920  UpdateSignature(signature_info,random_info->nonce);
921  FinalizeSignature(signature_info);
922  IncrementRandomNonce(random_info->nonce);
923  SetStringInfo(random_info->reservoir,GetSignatureDigest(signature_info));
924  random_info->i=i;
925  datum=GetStringInfoDatum(random_info->reservoir);
926  while (i-- != 0)
927  p[i]=datum[i];
928  }
929  UnlockSemaphoreInfo(random_info->semaphore);
930 }
931 
932 /*
933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934 % %
935 % %
936 % %
937 % S e t R a n d o m S e c r e t K e y %
938 % %
939 % %
940 % %
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 %
943 % SetRandomSecretKey() sets the pseudo-random number generator secret key.
944 %
945 % The format of the SetRandomSecretKey method is:
946 %
947 % void SetRandomSecretKey(const unsigned long key)
948 %
949 % A description of each parameter follows:
950 %
951 % o key: the secret key.
952 %
953 */
954 MagickExport void SetRandomSecretKey(const unsigned long key)
955 {
956  secret_key=key;
957 }
958 
959 /*
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961 % %
962 % %
963 % %
964 % S e t R a n d o m T r u e R a n d o m %
965 % %
966 % %
967 % %
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969 %
970 % SetRandomTrueRandom() declares your intentions to use true random numbers.
971 % True random numbers are encouraged but may not always be practical because
972 % your application may block while entropy is gathered from your environment.
973 %
974 % The format of the SetRandomTrueRandom method is:
975 %
976 % void SetRandomTrueRandom(const MagickBooleanType true_random)
977 %
978 % A description of each parameter follows:
979 %
980 % o true_random: declare your intentions to use true-random number.
981 %
982 */
984 {
985  gather_true_random=true_random;
986 }
StringInfo * nonce
Definition: random.c:85
static MagickThreadType GetMagickThreadId(void)
MagickPrivate void RandomComponentTerminus(void)
Definition: random.c:824
#define RandomProtocolMajorVersion
Definition: random.c:73
static ssize_t ReadRandom(int file, unsigned char *source, size_t length)
Definition: random.c:319
MagickExport StringInfo * StringToStringInfo(const char *string)
Definition: string.c:2475
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
#define ThrowFatalException(severity, tag)
MagickPrivate SignatureInfo * AcquireSignatureInfo(void)
#define MaxEntropyExtent
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
MagickPrivate void InitializeSignature(SignatureInfo *)
MagickExport void ConcatenateStringInfo(StringInfo *string_info, const StringInfo *source)
Definition: string.c:552
static void * AcquireCriticalMemory(const size_t size)
unsigned short protocol_minor
Definition: random.c:101
MagickExport void SetRandomTrueRandom(const MagickBooleanType true_random)
Definition: random.c:983
unsigned short protocol_major
Definition: random.c:101
#define O_BINARY
Definition: studio.h:325
Definition: log.h:52
MagickExport unsigned long GetRandomSecretKey(const RandomInfo *random_info)
Definition: random.c:742
MagickExport void SetRandomKey(RandomInfo *random_info, const size_t length, unsigned char *key)
Definition: random.c:877
MagickPrivate double GetRandomInfoNormalize(const RandomInfo *)
Definition: random.c:651
MagickExport RandomInfo * DestroyRandomInfo(RandomInfo *random_info)
Definition: random.c:273
#define MagickCoreSignature
MagickPrivate void FinalizeSignature(SignatureInfo *)
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickPrivate SignatureInfo * DestroySignatureInfo(SignatureInfo *)
Definition: signature.c:171
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1215
SemaphoreInfo * semaphore
Definition: random.c:105
SignatureInfo * signature_info
Definition: random.c:82
MagickBooleanType
Definition: magick-type.h:158
MagickExport char * AcquireString(const char *source)
Definition: string.c:129
MagickPrivate MagickBooleanType RandomComponentGenesis(void)
Definition: random.c:799
pid_t MagickThreadType
Definition: thread_.h:34
static int remove_utf8(const char *path)
MagickExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition: string.c:850
MagickExport void ResetStringInfo(StringInfo *string_info)
Definition: string.c:1592
unsigned long seed[4]
Definition: random.c:92
size_t i
Definition: random.c:89
#define MagickPathExtent
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1413
static int open_utf8(const char *path, int flags, mode_t mode)
MagickExport RandomInfo * AcquireRandomInfo(void)
Definition: random.c:163
MagickExport double GetPseudoRandomValue(RandomInfo *random_info)
Definition: random.c:609
static SemaphoreInfo * random_semaphore
Definition: random.c:131
MagickExport StringInfo * AcquireStringInfo(const size_t length)
Definition: string.c:187
MagickPrivate void UpdateSignature(SignatureInfo *, const StringInfo *)
Definition: signature.c:766
ssize_t timestamp
Definition: random.c:108
#define GetMagickModule()
Definition: log.h:28
MagickExport double GetRandomValue(RandomInfo *random_info)
Definition: random.c:767
static void IncrementRandomNonce(StringInfo *nonce)
Definition: random.c:859
MagickExport void SetStringInfoLength(StringInfo *string_info, const size_t length)
Definition: string.c:1745
static unsigned long secret_key
Definition: random.c:134
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
MagickPrivate unsigned long * GetRandomInfoSeed(RandomInfo *)
Definition: random.c:679
StringInfo * reservoir
Definition: random.c:85
unsigned long secret_key
Definition: random.c:98
size_t signature
Definition: random.c:111
char ** environ
#define MagickMin(x, y)
Definition: image-private.h:27
static RandomInfo * random_info
Definition: resource.c:113
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1069
double normalize
Definition: random.c:95
MagickPrivate const StringInfo * GetSignatureDigest(const SignatureInfo *)
Definition: signature.c:327
#define MagickPrivate
static StringInfo * GenerateEntropicChaos(RandomInfo *)
Definition: random.c:346
#define MagickExport
MagickExport StringInfo * GetRandomKey(RandomInfo *random_info, const size_t length)
Definition: random.c:709
static MagickBooleanType gather_true_random
Definition: random.c:137
MagickPrivate unsigned int GetSignatureDigestsize(const SignatureInfo *)
Definition: signature.c:358
MagickExport void SetRandomSecretKey(const unsigned long key)
Definition: random.c:954
MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
Definition: string.c:1244
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport void SetStringInfoDatum(StringInfo *string_info, const unsigned char *source)
Definition: string.c:1712
#define RandomProtocolMinorVersion
Definition: random.c:74
MagickExport void SetStringInfo(StringInfo *string_info, const StringInfo *source)
Definition: string.c:1672