Random.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "il2cpp-config.h"
  2. #include "vm/Random.h"
  3. #include "os/Cryptography.h"
  4. namespace il2cpp
  5. {
  6. namespace vm
  7. {
  8. bool Random::Open()
  9. {
  10. return il2cpp::os::Cryptography::OpenCryptographyProvider();
  11. }
  12. void* Random::Create()
  13. {
  14. il2cpp::os::Cryptography::OpenCryptographyProvider();
  15. return il2cpp::os::Cryptography::GetCryptographyProvider();
  16. }
  17. void Random::Free(void* handle)
  18. {
  19. il2cpp::os::Cryptography::ReleaseCryptographyProvider(handle);
  20. }
  21. /**
  22. * mono_rand_try_get_bytes:
  23. * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
  24. * @buffer: A buffer into which to write random data.
  25. * @buffer_size: Number of bytes to write into buffer.
  26. * @error: Set on error.
  27. *
  28. * Returns: FALSE on failure and sets @error, TRUE on success.
  29. *
  30. * Extracts bytes from an RNG handle.
  31. */
  32. bool Random::TryGetBytes(void* *handle, unsigned char *buffer, int buffer_size)
  33. {
  34. IL2CPP_ASSERT(handle);
  35. void* provider = *handle;
  36. if (!il2cpp::os::Cryptography::FillBufferWithRandomBytes(provider, buffer_size, buffer))
  37. {
  38. il2cpp::os::Cryptography::ReleaseCryptographyProvider(provider);
  39. /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */
  40. provider = il2cpp::os::Cryptography::GetCryptographyProvider();
  41. if (!il2cpp::os::Cryptography::FillBufferWithRandomBytes(provider, buffer_size, buffer))
  42. {
  43. il2cpp::os::Cryptography::ReleaseCryptographyProvider(provider);
  44. *handle = 0;
  45. //mono_error_set_execution_engine(error, "Failed to gen random bytes (%d)", GetLastError());
  46. return false;
  47. }
  48. }
  49. return true;
  50. }
  51. /**
  52. * mono_rand_try_get_uint32:
  53. * @handle: A pointer to an RNG handle. Handle is set to NULL on failure.
  54. * @val: A pointer to a 32-bit unsigned int, to which the result will be written.
  55. * @min: Result will be greater than or equal to this value.
  56. * @max: Result will be less than or equal to this value.
  57. *
  58. * Returns: FALSE on failure, TRUE on success.
  59. *
  60. * Extracts one 32-bit unsigned int from an RNG handle.
  61. */
  62. bool Random::TryGetUnsignedInt32(void* *handle, uint32_t *val, uint32_t min, uint32_t max)
  63. {
  64. IL2CPP_ASSERT(val);
  65. if (!TryGetBytes(handle, (unsigned char*)val, sizeof(uint32_t)))
  66. return false;
  67. double randomDouble = ((double)*val) / (((double)UINT32_MAX) + 1); // Range is [0,1)
  68. *val = (uint32_t)(randomDouble * (max - min + 1) + min);
  69. IL2CPP_ASSERT(*val >= min);
  70. IL2CPP_ASSERT(*val <= max);
  71. return true;
  72. }
  73. uint32_t Random::Next(void** handle, uint32_t min, uint32_t max)
  74. {
  75. uint32_t val;
  76. bool ok = TryGetUnsignedInt32(handle, &val, min, max);
  77. IL2CPP_ASSERT(ok);
  78. return val;
  79. }
  80. } /* namespace vm */
  81. } /* namespace il2cpp */