rand_linux.odin 908 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. package crypto
  2. import "core:fmt"
  3. import "core:sys/linux"
  4. HAS_RAND_BYTES :: true
  5. @(private)
  6. _MAX_PER_CALL_BYTES :: 33554431 // 2^25 - 1
  7. @(private)
  8. _rand_bytes :: proc (dst: []byte) {
  9. dst := dst
  10. l := len(dst)
  11. for l > 0 {
  12. to_read := min(l, _MAX_PER_CALL_BYTES)
  13. n_read, errno := linux.getrandom(dst[:to_read], {})
  14. #partial switch errno {
  15. case .NONE:
  16. // Do nothing
  17. case .EINTR:
  18. // Call interupted by a signal handler, just retry the
  19. // request.
  20. continue
  21. case .ENOSYS:
  22. // The kernel is apparently prehistoric (< 3.17 circa 2014)
  23. // and does not support getrandom.
  24. panic("crypto: getrandom not available in kernel")
  25. case:
  26. // All other failures are things that should NEVER happen
  27. // unless the kernel interface changes (ie: the Linux
  28. // developers break userland).
  29. fmt.panicf("crypto: getrandom failed: %v", errno)
  30. }
  31. l -= n_read
  32. dst = dst[n_read:]
  33. }
  34. }