blake2s_impl.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com>
  3. * Modified for CPython by Christian Heimes <christian@python.org>
  4. *
  5. * To the extent possible under law, the author have dedicated all
  6. * copyright and related and neighboring rights to this software to
  7. * the public domain worldwide. This software is distributed without
  8. * any warranty. http://creativecommons.org/publicdomain/zero/1.0/
  9. */
  10. /* WARNING: autogenerated file!
  11. *
  12. * The blake2s_impl.c is autogenerated from blake2s_impl.c.
  13. */
  14. #ifndef Py_BUILD_CORE_BUILTIN
  15. # define Py_BUILD_CORE_MODULE 1
  16. #endif
  17. #include "Python.h"
  18. #include "pycore_strhex.h" // _Py_strhex()
  19. #include "../hashlib.h"
  20. #include "blake2module.h"
  21. #ifndef HAVE_LIBB2
  22. /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+
  23. * https://bugs.python.org/issue31834 */
  24. #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__)
  25. #include "impl/blake2s.c"
  26. #else
  27. #include "impl/blake2s-ref.c"
  28. #endif
  29. #endif // !HAVE_LIBB2
  30. #define HAVE_BLAKE2S 1
  31. extern PyType_Spec blake2s_type_spec;
  32. typedef struct {
  33. PyObject_HEAD
  34. blake2s_param param;
  35. blake2s_state state;
  36. PyThread_type_lock lock;
  37. } BLAKE2sObject;
  38. #include "clinic/blake2s_impl.c.h"
  39. /*[clinic input]
  40. module _blake2
  41. class _blake2.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType"
  42. [clinic start generated code]*/
  43. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b79d7ffe07286ce]*/
  44. static BLAKE2sObject *
  45. new_BLAKE2sObject(PyTypeObject *type)
  46. {
  47. BLAKE2sObject *self;
  48. self = (BLAKE2sObject *)type->tp_alloc(type, 0);
  49. if (self != NULL) {
  50. self->lock = NULL;
  51. }
  52. return self;
  53. }
  54. /*[clinic input]
  55. @classmethod
  56. _blake2.blake2s.__new__ as py_blake2s_new
  57. data: object(c_default="NULL") = b''
  58. /
  59. *
  60. digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2.blake2s.MAX_DIGEST_SIZE
  61. key: Py_buffer(c_default="NULL", py_default="b''") = None
  62. salt: Py_buffer(c_default="NULL", py_default="b''") = None
  63. person: Py_buffer(c_default="NULL", py_default="b''") = None
  64. fanout: int = 1
  65. depth: int = 1
  66. leaf_size: unsigned_long = 0
  67. node_offset: unsigned_long_long = 0
  68. node_depth: int = 0
  69. inner_size: int = 0
  70. last_node: bool = False
  71. usedforsecurity: bool = True
  72. Return a new BLAKE2s hash object.
  73. [clinic start generated code]*/
  74. static PyObject *
  75. py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
  76. Py_buffer *key, Py_buffer *salt, Py_buffer *person,
  77. int fanout, int depth, unsigned long leaf_size,
  78. unsigned long long node_offset, int node_depth,
  79. int inner_size, int last_node, int usedforsecurity)
  80. /*[clinic end generated code: output=556181f73905c686 input=4dda87723f23abb0]*/
  81. {
  82. BLAKE2sObject *self = NULL;
  83. Py_buffer buf;
  84. self = new_BLAKE2sObject(type);
  85. if (self == NULL) {
  86. goto error;
  87. }
  88. /* Zero parameter block. */
  89. memset(&self->param, 0, sizeof(self->param));
  90. /* Set digest size. */
  91. if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) {
  92. PyErr_Format(PyExc_ValueError,
  93. "digest_size must be between 1 and %d bytes",
  94. BLAKE2S_OUTBYTES);
  95. goto error;
  96. }
  97. self->param.digest_length = digest_size;
  98. /* Set salt parameter. */
  99. if ((salt->obj != NULL) && salt->len) {
  100. if (salt->len > BLAKE2S_SALTBYTES) {
  101. PyErr_Format(PyExc_ValueError,
  102. "maximum salt length is %d bytes",
  103. BLAKE2S_SALTBYTES);
  104. goto error;
  105. }
  106. memcpy(self->param.salt, salt->buf, salt->len);
  107. }
  108. /* Set personalization parameter. */
  109. if ((person->obj != NULL) && person->len) {
  110. if (person->len > BLAKE2S_PERSONALBYTES) {
  111. PyErr_Format(PyExc_ValueError,
  112. "maximum person length is %d bytes",
  113. BLAKE2S_PERSONALBYTES);
  114. goto error;
  115. }
  116. memcpy(self->param.personal, person->buf, person->len);
  117. }
  118. /* Set tree parameters. */
  119. if (fanout < 0 || fanout > 255) {
  120. PyErr_SetString(PyExc_ValueError,
  121. "fanout must be between 0 and 255");
  122. goto error;
  123. }
  124. self->param.fanout = (uint8_t)fanout;
  125. if (depth <= 0 || depth > 255) {
  126. PyErr_SetString(PyExc_ValueError,
  127. "depth must be between 1 and 255");
  128. goto error;
  129. }
  130. self->param.depth = (uint8_t)depth;
  131. if (leaf_size > 0xFFFFFFFFU) {
  132. PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
  133. goto error;
  134. }
  135. // NB: Simple assignment here would be incorrect on big endian platforms.
  136. store32(&(self->param.leaf_length), leaf_size);
  137. #ifdef HAVE_BLAKE2S
  138. if (node_offset > 0xFFFFFFFFFFFFULL) {
  139. /* maximum 2**48 - 1 */
  140. PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
  141. goto error;
  142. }
  143. store48(&(self->param.node_offset), node_offset);
  144. #else
  145. // NB: Simple assignment here would be incorrect on big endian platforms.
  146. store64(&(self->param.node_offset), node_offset);
  147. #endif
  148. if (node_depth < 0 || node_depth > 255) {
  149. PyErr_SetString(PyExc_ValueError,
  150. "node_depth must be between 0 and 255");
  151. goto error;
  152. }
  153. self->param.node_depth = node_depth;
  154. if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) {
  155. PyErr_Format(PyExc_ValueError,
  156. "inner_size must be between 0 and is %d",
  157. BLAKE2S_OUTBYTES);
  158. goto error;
  159. }
  160. self->param.inner_length = inner_size;
  161. /* Set key length. */
  162. if ((key->obj != NULL) && key->len) {
  163. if (key->len > BLAKE2S_KEYBYTES) {
  164. PyErr_Format(PyExc_ValueError,
  165. "maximum key length is %d bytes",
  166. BLAKE2S_KEYBYTES);
  167. goto error;
  168. }
  169. self->param.key_length = (uint8_t)key->len;
  170. }
  171. /* Initialize hash state. */
  172. if (blake2s_init_param(&self->state, &self->param) < 0) {
  173. PyErr_SetString(PyExc_RuntimeError,
  174. "error initializing hash state");
  175. goto error;
  176. }
  177. /* Set last node flag (must come after initialization). */
  178. self->state.last_node = last_node;
  179. /* Process key block if any. */
  180. if (self->param.key_length) {
  181. uint8_t block[BLAKE2S_BLOCKBYTES];
  182. memset(block, 0, sizeof(block));
  183. memcpy(block, key->buf, key->len);
  184. blake2s_update(&self->state, block, sizeof(block));
  185. secure_zero_memory(block, sizeof(block));
  186. }
  187. /* Process initial data if any. */
  188. if (data != NULL) {
  189. GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
  190. if (buf.len >= HASHLIB_GIL_MINSIZE) {
  191. Py_BEGIN_ALLOW_THREADS
  192. blake2s_update(&self->state, buf.buf, buf.len);
  193. Py_END_ALLOW_THREADS
  194. } else {
  195. blake2s_update(&self->state, buf.buf, buf.len);
  196. }
  197. PyBuffer_Release(&buf);
  198. }
  199. return (PyObject *)self;
  200. error:
  201. if (self != NULL) {
  202. Py_DECREF(self);
  203. }
  204. return NULL;
  205. }
  206. /*[clinic input]
  207. _blake2.blake2s.copy
  208. Return a copy of the hash object.
  209. [clinic start generated code]*/
  210. static PyObject *
  211. _blake2_blake2s_copy_impl(BLAKE2sObject *self)
  212. /*[clinic end generated code: output=5b90131c4eae275e input=0b9d44942f0fe4b2]*/
  213. {
  214. BLAKE2sObject *cpy;
  215. if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL)
  216. return NULL;
  217. ENTER_HASHLIB(self);
  218. cpy->param = self->param;
  219. cpy->state = self->state;
  220. LEAVE_HASHLIB(self);
  221. return (PyObject *)cpy;
  222. }
  223. /*[clinic input]
  224. _blake2.blake2s.update
  225. data: object
  226. /
  227. Update this hash object's state with the provided bytes-like object.
  228. [clinic start generated code]*/
  229. static PyObject *
  230. _blake2_blake2s_update(BLAKE2sObject *self, PyObject *data)
  231. /*[clinic end generated code: output=757dc087fec37815 input=97500db2f9de4aaa]*/
  232. {
  233. Py_buffer buf;
  234. GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
  235. if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
  236. self->lock = PyThread_allocate_lock();
  237. if (self->lock != NULL) {
  238. Py_BEGIN_ALLOW_THREADS
  239. PyThread_acquire_lock(self->lock, 1);
  240. blake2s_update(&self->state, buf.buf, buf.len);
  241. PyThread_release_lock(self->lock);
  242. Py_END_ALLOW_THREADS
  243. } else {
  244. blake2s_update(&self->state, buf.buf, buf.len);
  245. }
  246. PyBuffer_Release(&buf);
  247. Py_RETURN_NONE;
  248. }
  249. /*[clinic input]
  250. _blake2.blake2s.digest
  251. Return the digest value as a bytes object.
  252. [clinic start generated code]*/
  253. static PyObject *
  254. _blake2_blake2s_digest_impl(BLAKE2sObject *self)
  255. /*[clinic end generated code: output=40c566ca4bc6bc51 input=f41e0b8d6d937454]*/
  256. {
  257. uint8_t digest[BLAKE2S_OUTBYTES];
  258. blake2s_state state_cpy;
  259. ENTER_HASHLIB(self);
  260. state_cpy = self->state;
  261. blake2s_final(&state_cpy, digest, self->param.digest_length);
  262. LEAVE_HASHLIB(self);
  263. return PyBytes_FromStringAndSize((const char *)digest,
  264. self->param.digest_length);
  265. }
  266. /*[clinic input]
  267. _blake2.blake2s.hexdigest
  268. Return the digest value as a string of hexadecimal digits.
  269. [clinic start generated code]*/
  270. static PyObject *
  271. _blake2_blake2s_hexdigest_impl(BLAKE2sObject *self)
  272. /*[clinic end generated code: output=15153eb5e59c52eb input=c77a1321567e8952]*/
  273. {
  274. uint8_t digest[BLAKE2S_OUTBYTES];
  275. blake2s_state state_cpy;
  276. ENTER_HASHLIB(self);
  277. state_cpy = self->state;
  278. blake2s_final(&state_cpy, digest, self->param.digest_length);
  279. LEAVE_HASHLIB(self);
  280. return _Py_strhex((const char *)digest, self->param.digest_length);
  281. }
  282. static PyMethodDef py_blake2s_methods[] = {
  283. _BLAKE2_BLAKE2S_COPY_METHODDEF
  284. _BLAKE2_BLAKE2S_DIGEST_METHODDEF
  285. _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF
  286. _BLAKE2_BLAKE2S_UPDATE_METHODDEF
  287. {NULL, NULL}
  288. };
  289. static PyObject *
  290. py_blake2s_get_name(BLAKE2sObject *self, void *closure)
  291. {
  292. return PyUnicode_FromString("blake2s");
  293. }
  294. static PyObject *
  295. py_blake2s_get_block_size(BLAKE2sObject *self, void *closure)
  296. {
  297. return PyLong_FromLong(BLAKE2S_BLOCKBYTES);
  298. }
  299. static PyObject *
  300. py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure)
  301. {
  302. return PyLong_FromLong(self->param.digest_length);
  303. }
  304. static PyGetSetDef py_blake2s_getsetters[] = {
  305. {"name", (getter)py_blake2s_get_name,
  306. NULL, NULL, NULL},
  307. {"block_size", (getter)py_blake2s_get_block_size,
  308. NULL, NULL, NULL},
  309. {"digest_size", (getter)py_blake2s_get_digest_size,
  310. NULL, NULL, NULL},
  311. {NULL}
  312. };
  313. static void
  314. py_blake2s_dealloc(PyObject *self)
  315. {
  316. BLAKE2sObject *obj = (BLAKE2sObject *)self;
  317. /* Try not to leave state in memory. */
  318. secure_zero_memory(&obj->param, sizeof(obj->param));
  319. secure_zero_memory(&obj->state, sizeof(obj->state));
  320. if (obj->lock) {
  321. PyThread_free_lock(obj->lock);
  322. obj->lock = NULL;
  323. }
  324. PyTypeObject *type = Py_TYPE(self);
  325. PyObject_Free(self);
  326. Py_DECREF(type);
  327. }
  328. static PyType_Slot blake2s_type_slots[] = {
  329. {Py_tp_dealloc, py_blake2s_dealloc},
  330. {Py_tp_doc, (char *)py_blake2s_new__doc__},
  331. {Py_tp_methods, py_blake2s_methods},
  332. {Py_tp_getset, py_blake2s_getsetters},
  333. {Py_tp_new, py_blake2s_new},
  334. {0,0}
  335. };
  336. PyType_Spec blake2s_type_spec = {
  337. .name = "_blake2.blake2s",
  338. .basicsize = sizeof(BLAKE2sObject),
  339. .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
  340. .slots = blake2s_type_slots
  341. };