summaryrefslogtreecommitdiffstats
path: root/rand.py
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2018-06-03 16:37:42 +0200
committerMatěj Cepl <mcepl@cepl.eu>2018-06-03 16:37:42 +0200
commiteecb91038ff27db8b1c71103a2bc3711e2a0b00d (patch)
tree00db272741c5265878815f8c7b375eb163bea691 /rand.py
parentf329e17cf7401eb8ab7f9ae1f6a3833af64b011b (diff)
downloadplay_with_bindings-master.tar.gz
More cffi beauty, some testsHEADmaster
Diffstat (limited to 'rand.py')
-rw-r--r--rand.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/rand.py b/rand.py
new file mode 100644
index 0000000..285eb98
--- /dev/null
+++ b/rand.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+import sys
+from typing import Optional
+
+from cffi import FFI
+
+class RandError(RuntimeError):
+ pass
+
+ffi = FFI()
+ffi.cdef('''
+ void RAND_seed(const void *buf, int num);
+
+ void RAND_add(const void *buf, int num, double entropy);
+
+ int RAND_status(void);
+
+ int RAND_event(unsigned int iMsg, void* wParam, void* lParam);
+ void RAND_screen(void);
+
+ int RAND_bytes(unsigned char *buf, int num);
+
+ int RAND_pseudo_bytes(unsigned char *buf, int num);
+
+ const char *ERR_reason_error_string(unsigned long);
+
+ unsigned long ERR_get_error(void);
+''')
+
+lib = ffi.dlopen('crypto')
+
+def rand_add(buf: bytes, num: int, entropy: float) -> None:
+ assert isinstance(entropy, float)
+ lib.RAND_add(buf, num, entropy)
+
+def rand_seed(buf: bytes, num: int) -> None:
+ lib.RAND_seed(buf, num)
+
+def rand_status() -> int:
+ return lib.RAND_status()
+
+def rand_event(iMsg: int, wParam: int, lParam: int) -> Optional[int]:
+ if sys.platform == 'win32':
+ return lib.RAND_event(iMsg, wParam, lParam)
+ else:
+ return None
+
+def rand_screen() -> None:
+ if sys.platform == 'win32':
+ lib.RAND_screen()
+
+def rand_bytes(n: int = 8) -> bytes:
+ buf = ffi.new('unsigned char buf[{:d}]'.format(n))
+ ret = lib.RAND_bytes(buf, n)
+ if ret == 1:
+ return bytes(buf)
+ elif ret == 0:
+ RandError("Not enough randomness.")
+ elif ret == -1:
+ RandError("Not supported by the current RAND method.")
+ else:
+ err_msg = lib.ERR_reason_error_string(lib.ERR_get_error())
+ if err_msg is not None:
+ RandError(err_msg)
+ else:
+ RandError("Unknown error in function RAND_bytes")
+
+def rand_pseudo_bytes(n: int) -> bytes:
+ blob = ffi.new('unsigned char buf[{:d}]'.format(n))
+ ret = lib.RAND_pseudo_bytes(blob, n)
+
+ if ret == -1:
+ RandError("Not supported by the current RAND method.")
+ elif ret in [0, 1]:
+ return (bytes(blob), ret)
+ else:
+ RandError("Unknown error in RAND_pseudo_bytes")