PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/gdata/tlslite/utils/entropy.c

https://gitlab.com/gregtyka/khanacademy
C | 173 lines | 112 code | 41 blank | 20 comment | 20 complexity | d1809e936e59e78373d037c929b7e772 MD5 | raw file
  1. #include "Python.h"
  2. #ifdef MS_WINDOWS
  3. /* The following #define is not needed on VC6 with the Platform SDK, and it
  4. may not be needed on VC7, I'm not sure. I don't think it hurts anything.*/
  5. #define _WIN32_WINNT 0x0400
  6. #include <windows.h>
  7. typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
  8. LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
  9. DWORD dwFlags );
  10. typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
  11. BYTE *pbBuffer );
  12. typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\
  13. DWORD dwFlags);
  14. static PyObject* entropy(PyObject *self, PyObject *args)
  15. {
  16. int howMany = 0;
  17. HINSTANCE hAdvAPI32 = NULL;
  18. CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL;
  19. CRYPTGENRANDOM pCryptGenRandom = NULL;
  20. CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
  21. HCRYPTPROV hCryptProv = 0;
  22. unsigned char* bytes = NULL;
  23. PyObject* returnVal = NULL;
  24. /* Read arguments */
  25. if (!PyArg_ParseTuple(args, "i", &howMany))
  26. return(NULL);
  27. /* Obtain handle to the DLL containing CryptoAPI
  28. This should not fail */
  29. if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) {
  30. PyErr_Format(PyExc_SystemError,
  31. "Advapi32.dll not found");
  32. return NULL;
  33. }
  34. /* Obtain pointers to the CryptoAPI functions
  35. This will fail on some early version of Win95 */
  36. pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\
  37. "CryptAcquireContextA");
  38. pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\
  39. "CryptGenRandom");
  40. pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\
  41. "CryptReleaseContext");
  42. if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL ||
  43. pCryptReleaseContext == NULL) {
  44. PyErr_Format(PyExc_NotImplementedError,
  45. "CryptoAPI not available on this version of Windows");
  46. return NULL;
  47. }
  48. /* Allocate bytes */
  49. if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
  50. return PyErr_NoMemory();
  51. /* Acquire context */
  52. if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
  53. CRYPT_VERIFYCONTEXT)) {
  54. PyErr_Format(PyExc_SystemError,
  55. "CryptAcquireContext failed, error %d", GetLastError());
  56. PyMem_Free(bytes);
  57. return NULL;
  58. }
  59. /* Get random data */
  60. if(!pCryptGenRandom(hCryptProv, howMany, bytes)) {
  61. PyErr_Format(PyExc_SystemError,
  62. "CryptGenRandom failed, error %d", GetLastError());
  63. PyMem_Free(bytes);
  64. CryptReleaseContext(hCryptProv, 0);
  65. return NULL;
  66. }
  67. /* Build return value */
  68. returnVal = Py_BuildValue("s#", bytes, howMany);
  69. PyMem_Free(bytes);
  70. /* Release context */
  71. if (!pCryptReleaseContext(hCryptProv, 0)) {
  72. PyErr_Format(PyExc_SystemError,
  73. "CryptReleaseContext failed, error %d", GetLastError());
  74. return NULL;
  75. }
  76. return returnVal;
  77. }
  78. #elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H)
  79. #include <unistd.h>
  80. #include <fcntl.h>
  81. static PyObject* entropy(PyObject *self, PyObject *args)
  82. {
  83. int howMany;
  84. int fd;
  85. unsigned char* bytes = NULL;
  86. PyObject* returnVal = NULL;
  87. /* Read arguments */
  88. if (!PyArg_ParseTuple(args, "i", &howMany))
  89. return(NULL);
  90. /* Allocate bytes */
  91. if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL)
  92. return PyErr_NoMemory();
  93. /* Open device */
  94. if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) {
  95. PyErr_Format(PyExc_NotImplementedError,
  96. "No entropy source found");
  97. PyMem_Free(bytes);
  98. return NULL;
  99. }
  100. /* Get random data */
  101. if (read(fd, bytes, howMany) < howMany) {
  102. PyErr_Format(PyExc_SystemError,
  103. "Reading from /dev/urandom failed");
  104. PyMem_Free(bytes);
  105. close(fd);
  106. return NULL;
  107. }
  108. /* Build return value */
  109. returnVal = Py_BuildValue("s#", bytes, howMany);
  110. PyMem_Free(bytes);
  111. /* Close device */
  112. close(fd);
  113. return returnVal;
  114. }
  115. #else
  116. static PyObject* entropy(PyObject *self, PyObject *args)
  117. {
  118. PyErr_Format(PyExc_NotImplementedError,
  119. "Function not supported");
  120. return NULL;
  121. }
  122. #endif
  123. /* List of functions exported by this module */
  124. static struct PyMethodDef entropy_functions[] = {
  125. {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."},
  126. {NULL, NULL} /* Sentinel */
  127. };
  128. /* Initialize this module. */
  129. PyMODINIT_FUNC initentropy(void)
  130. {
  131. Py_InitModule("entropy", entropy_functions);
  132. }