暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

pal_random.cpp 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "il2cpp-config.h"
  2. #include "pal_platform.h"
  3. #if IL2CPP_USES_POSIX_CLASS_LIBRARY_PAL
  4. #define IL2CPP_HAVE_O_CLOEXEC 1
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <errno.h>
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include <unistd.h>
  11. extern "C"
  12. {
  13. // Items needed by mscorlib
  14. IL2CPP_EXPORT void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int32_t bufferLength);
  15. }
  16. void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int32_t bufferLength)
  17. {
  18. IL2CPP_ASSERT(buffer != NULL);
  19. #if IL2CPP_HAVE_ARC4RANDOM_BUF
  20. arc4random_buf(buffer, (size_t)bufferLength);
  21. #else
  22. static volatile int rand_des = -1;
  23. long num = 0;
  24. static bool sMissingDevURandom;
  25. static bool sInitializedMRand;
  26. if (!sMissingDevURandom)
  27. {
  28. if (rand_des == -1)
  29. {
  30. int fd;
  31. do
  32. {
  33. #if IL2CPP_HAVE_O_CLOEXEC
  34. fd = open("/dev/urandom", O_RDONLY, O_CLOEXEC);
  35. #else
  36. fd = open("/dev/urandom", O_RDONLY);
  37. fcntl(fd, F_SETFD, FD_CLOEXEC);
  38. #endif
  39. }
  40. while ((fd == -1) && (errno == EINTR));
  41. if (fd != -1)
  42. {
  43. if (!__sync_bool_compare_and_swap(&rand_des, -1, fd))
  44. {
  45. // Another thread has already set the rand_des
  46. close(fd);
  47. }
  48. }
  49. else if (errno == ENOENT)
  50. {
  51. sMissingDevURandom = true;
  52. }
  53. }
  54. if (rand_des != -1)
  55. {
  56. int32_t offset = 0;
  57. do
  58. {
  59. ssize_t n = read(rand_des, buffer + offset , (size_t)(bufferLength - offset));
  60. if (n == -1)
  61. {
  62. if (errno == EINTR)
  63. {
  64. continue;
  65. }
  66. IL2CPP_ASSERT(false && "read from /dev/urandom has failed");
  67. break;
  68. }
  69. offset += n;
  70. }
  71. while (offset != bufferLength);
  72. }
  73. }
  74. if (!sInitializedMRand)
  75. {
  76. srand48(time(NULL));
  77. sInitializedMRand = true;
  78. }
  79. // always xor srand48 over the whole buffer to get some randomness
  80. // in case /dev/urandom is not really random
  81. for (int i = 0; i < bufferLength; i++)
  82. {
  83. if (i % 4 == 0)
  84. {
  85. num = lrand48();
  86. }
  87. *(buffer + i) ^= num;
  88. num >>= 8;
  89. }
  90. #endif // IL2CPP_HAVE_ARC4RANDOM_BUF
  91. }
  92. #endif