1515#define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
1616#endif
1717
18+ // Some compatibility defines for CPython < 3.13
19+
20+ #if PY_VERSION_HEX < 0x030d0000
21+ typedef struct { int v ; } PyMutex ;
22+ #define PyMutex_Lock (m ) ((void)(m))
23+ #define PyMutex_Unlock (m ) ((void)(m))
24+ #endif
25+
1826// Some compatibility defines for CPython < 3.11
1927
2028#ifndef _PyCFunction_CAST
@@ -59,6 +67,7 @@ get_pystandalone_state(PyObject *module)
5967
6068typedef struct {
6169 PyObject_HEAD
70+ PyMutex mutex ;
6271 EVP_CIPHER_CTX * ctx ; /* OpenSSL cipher context */
6372 unsigned char key [EVP_MAX_KEY_LENGTH ];
6473 unsigned char iv [EVP_MAX_IV_LENGTH ];
@@ -68,6 +77,7 @@ typedef struct {
6877
6978typedef struct {
7079 PyObject_HEAD
80+ PyMutex mutex ;
7181 EVP_PKEY_CTX * ctx ; /* OpenSSL pkey context */
7282} PublicKey ;
7383
@@ -480,7 +490,10 @@ static PyObject *
480490_pystandalone_Cipher_encrypt_impl (Cipher * self , Py_buffer * data )
481491/*[clinic end generated code: output=905ce94ccf6e0082 input=17d62fae407625b9]*/
482492{
483- return _Cipher_crypt (self , data , CIPHER_MODE_ENCRYPT );
493+ PyMutex_Lock (& self -> mutex );
494+ PyObject * res = _Cipher_crypt (self , data , CIPHER_MODE_ENCRYPT );
495+ PyMutex_Unlock (& self -> mutex );
496+ return res ;
484497}
485498
486499/*[clinic input]
@@ -497,17 +510,23 @@ _pystandalone_Cipher_encrypt_and_digest_impl(Cipher *self, Py_buffer *data)
497510{
498511 PyObject * buf , * digest ;
499512
513+ PyMutex_Lock (& self -> mutex );
514+
500515 buf = _Cipher_crypt (self , data , CIPHER_MODE_ENCRYPT );
501516 if (buf == NULL ) {
517+ PyMutex_Unlock (& self -> mutex );
502518 return NULL ;
503519 }
504520
505521 digest = _Cipher_get_tag (self );
506522 if (digest == NULL ) {
523+ PyMutex_Unlock (& self -> mutex );
507524 Py_DECREF (buf );
508525 return NULL ;
509526 }
510527
528+ PyMutex_Unlock (& self -> mutex );
529+
511530 return PyTuple_Pack (2 , buf , digest );
512531}
513532
@@ -523,7 +542,10 @@ static PyObject *
523542_pystandalone_Cipher_decrypt_impl (Cipher * self , Py_buffer * data )
524543/*[clinic end generated code: output=dd94f41ddbeaccf7 input=363abf129f94df00]*/
525544{
526- return _Cipher_crypt (self , data , CIPHER_MODE_DECRYPT );
545+ PyMutex_Lock (& self -> mutex );
546+ PyObject * res = _Cipher_crypt (self , data , CIPHER_MODE_DECRYPT );
547+ PyMutex_Unlock (& self -> mutex );
548+ return res ;
527549}
528550
529551/*[clinic input]
@@ -544,16 +566,22 @@ _pystandalone_Cipher_decrypt_and_verify_impl(Cipher *self, Py_buffer *data,
544566{
545567 PyObject * buf ;
546568
569+ PyMutex_Lock (& self -> mutex );
570+
547571 buf = _Cipher_crypt (self , data , CIPHER_MODE_DECRYPT );
548572 if (buf == NULL ) {
573+ PyMutex_Unlock (& self -> mutex );
549574 return NULL ;
550575 }
551576
552577 if (_Cipher_verify_tag (self , tag ) == NULL ) {
578+ PyMutex_Unlock (& self -> mutex );
553579 Py_DECREF (buf );
554580 return NULL ;
555581 }
556582
583+ PyMutex_Unlock (& self -> mutex );
584+
557585 return buf ;
558586}
559587
@@ -569,7 +597,10 @@ static PyObject *
569597_pystandalone_Cipher_update_impl (Cipher * self , Py_buffer * data )
570598/*[clinic end generated code: output=8aea00e2c0e763eb input=ce774ce7ddc5e8c9]*/
571599{
572- return _Cipher_update_ad (self , data );
600+ PyMutex_Lock (& self -> mutex );
601+ PyObject * res = _Cipher_update_ad (self , data );
602+ PyMutex_Unlock (& self -> mutex );
603+ return res ;
573604}
574605
575606/*[clinic input]
@@ -582,7 +613,10 @@ static PyObject *
582613_pystandalone_Cipher_digest_impl (Cipher * self )
583614/*[clinic end generated code: output=ca0c92f67a3aac6d input=d92ff14e2380d3e4]*/
584615{
585- return _Cipher_get_tag (self );
616+ PyMutex_Lock (& self -> mutex );
617+ PyObject * res = _Cipher_get_tag (self );
618+ PyMutex_Unlock (& self -> mutex );
619+ return res ;
586620}
587621
588622/*[clinic input]
@@ -597,7 +631,10 @@ static PyObject *
597631_pystandalone_Cipher_verify_impl (Cipher * self , Py_buffer * tag )
598632/*[clinic end generated code: output=2c8e2d72c015c078 input=cf4d4fd1a495c7f7]*/
599633{
600- return _Cipher_verify_tag (self , tag );
634+ PyMutex_Lock (& self -> mutex );
635+ PyObject * res = _Cipher_verify_tag (self , tag );
636+ PyMutex_Unlock (& self -> mutex );
637+ return res ;
601638}
602639
603640/*[clinic input]
@@ -610,7 +647,9 @@ static PyObject *
610647_pystandalone_Cipher_clean_impl (Cipher * self )
611648/*[clinic end generated code: output=fa8d7c88cbdea4c8 input=e334120cdcc73ca7]*/
612649{
650+ PyMutex_Lock (& self -> mutex );
613651 _Cipher_clean (self );
652+ PyMutex_Unlock (& self -> mutex );
614653 Py_RETURN_NONE ;
615654}
616655
@@ -629,22 +668,28 @@ static PyMethodDef Cipher_methods[] = {
629668static PyObject *
630669Cipher_get_initialized (Cipher * self , void * closure )
631670{
632- PyObject * res = self -> state == CIPHER_STATE_INIT ? Py_True : Py_False ;
633- return Py_INCREF (res ), res ;
671+ PyMutex_Lock (& self -> mutex );
672+ int initialized = self -> state == CIPHER_STATE_INIT ;
673+ PyMutex_Unlock (& self -> mutex );
674+ return PyBool_FromLong (initialized );
634675}
635676
636677static PyObject *
637678Cipher_get_finalized (Cipher * self , void * closure )
638679{
639- PyObject * res = self -> state == CIPHER_STATE_FINAL ? Py_True : Py_False ;
640- return Py_INCREF (res ), res ;
680+ PyMutex_Lock (& self -> mutex );
681+ int finalized = self -> state == CIPHER_STATE_FINAL ;
682+ PyMutex_Unlock (& self -> mutex );
683+ return PyBool_FromLong (finalized );
641684}
642685
643686static PyObject *
644687Cipher_get_cleaned (Cipher * self , void * closure )
645688{
646- PyObject * res = self -> state == CIPHER_STATE_CLEAR ? Py_True : Py_False ;
647- return Py_INCREF (res ), res ;
689+ PyMutex_Lock (& self -> mutex );
690+ int cleaned = self -> state == CIPHER_STATE_CLEAR ;
691+ PyMutex_Unlock (& self -> mutex );
692+ return PyBool_FromLong (cleaned );
648693}
649694
650695static PyObject *
@@ -700,11 +745,13 @@ Cipher_repr(Cipher *self)
700745static void
701746Cipher_dealloc (Cipher * self )
702747{
748+ PyTypeObject * tp = Py_TYPE (self );
703749 EVP_CIPHER_CTX_cleanup (self -> ctx );
704750 EVP_CIPHER_CTX_free (self -> ctx );
705751 OPENSSL_cleanse (self -> key , sizeof (self -> key ));
706752 OPENSSL_cleanse (self -> iv , sizeof (self -> iv ));
707- PyObject_Del (self );
753+ PyObject_Free (self );
754+ Py_DECREF (tp );
708755}
709756
710757static int
@@ -850,24 +897,31 @@ _pystandalone_PublicKey_encrypt_impl(PublicKey *self, Py_buffer *data)
850897 size_t out_len ;
851898 unsigned char * out_buf ;
852899
900+ PyMutex_Lock (& self -> mutex );
901+
853902 if (!EVP_PKEY_encrypt (self -> ctx , NULL , & out_len , data -> buf , data -> len )) {
903+ PyMutex_Unlock (& self -> mutex );
854904 _set_exception (PyExc_ValueError );
855905 return NULL ;
856906 }
857907
858908 buf = PyBytes_FromStringAndSize (NULL , out_len );
859909 if (buf == NULL ) {
910+ PyMutex_Unlock (& self -> mutex );
860911 PyErr_NoMemory ();
861912 return NULL ;
862913 }
863914
864915 out_buf = (unsigned char * )PyBytes_AS_STRING (buf );
865916 if (!EVP_PKEY_encrypt (self -> ctx , out_buf , & out_len , data -> buf , data -> len )) {
917+ PyMutex_Unlock (& self -> mutex );
866918 _set_exception (PyExc_ValueError );
867919 Py_DECREF (buf );
868920 return NULL ;
869921 }
870922
923+ PyMutex_Unlock (& self -> mutex );
924+
871925 return buf ;
872926}
873927
@@ -977,8 +1031,10 @@ PublicKey_repr(PublicKey *self)
9771031static void
9781032PublicKey_dealloc (PublicKey * self )
9791033{
1034+ PyTypeObject * tp = Py_TYPE (self );
9801035 EVP_PKEY_CTX_free (self -> ctx );
981- PyObject_Del (self );
1036+ PyObject_Free (self );
1037+ Py_DECREF (tp );
9821038}
9831039
9841040static int
@@ -1132,8 +1188,7 @@ static PyObject *
11321188_pystandalone_has_library_impl (PyObject * module )
11331189/*[clinic end generated code: output=04238eaa01e29446 input=3272862d1d74a71a]*/
11341190{
1135- PyObject * res = PyStandalone_HasLibrary () ? Py_True : Py_False ;
1136- return Py_INCREF (res ), res ;
1191+ return PyBool_FromLong (PyStandalone_HasLibrary ());
11371192}
11381193
11391194/*[clinic input]
@@ -1146,8 +1201,7 @@ static PyObject *
11461201_pystandalone_has_bootstrap_impl (PyObject * module )
11471202/*[clinic end generated code: output=a5e616490f5e50c9 input=24807adbd6092d18]*/
11481203{
1149- PyObject * res = PyStandalone_HasBootstrap () ? Py_True : Py_False ;
1150- return Py_INCREF (res ), res ;
1204+ return PyBool_FromLong (PyStandalone_HasBootstrap ());
11511205}
11521206
11531207/*[clinic input]
@@ -1160,8 +1214,7 @@ static PyObject *
11601214_pystandalone_has_payload_impl (PyObject * module )
11611215/*[clinic end generated code: output=3f6b9eeea5cb6ba3 input=338fbe7842bbb2dd]*/
11621216{
1163- PyObject * res = PyStandalone_HasPayload () ? Py_True : Py_False ;
1164- return Py_INCREF (res ), res ;
1217+ return PyBool_FromLong (PyStandalone_HasPayload ());
11651218}
11661219
11671220/* List of functions exported by this module */
@@ -1306,6 +1359,9 @@ _pystandalone_free(void *module)
13061359static struct PyModuleDef_Slot _pystandalone_slots [] = {
13071360 {Py_mod_exec , _pystandalone_init_types },
13081361 {Py_mod_exec , _pystandalone_init_cipher_names },
1362+ #ifdef Py_GIL_DISABLED
1363+ {Py_mod_gil , Py_MOD_GIL_NOT_USED },
1364+ #endif
13091365 {0 , NULL }
13101366};
13111367
0 commit comments