Skip to content

Commit a46976a

Browse files
committed
[3.14] pythongh-136968: fortify macro usage in cryptographic modules (pythonGH-136973)
Macros used in cryptographic extension modules are partially rewritten to use `static inline` functions when possible to help code completion. (cherry picked from commit eefd70f) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 47a2109 commit a46976a

File tree

3 files changed

+115
-77
lines changed

3 files changed

+115
-77
lines changed

Modules/_hashopenssl.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,14 +1017,11 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj,
10171017
return (PyObject *)self;
10181018
}
10191019

1020+
// In Python 3.19, we can remove the "STRING" argument and would also be able
1021+
// to remove the macro (or keep it as an alias for better naming) since calls
1022+
// to _hashlib_new_impl() would fit on 80 characters.
10201023
#define CALL_HASHLIB_NEW(MODULE, NAME, DATA, STRING, USEDFORSECURITY) \
1021-
do { \
1022-
PyObject *data_obj; \
1023-
if (_Py_hashlib_data_argument(&data_obj, DATA, STRING) < 0) { \
1024-
return NULL; \
1025-
} \
1026-
return _hashlib_HASH(MODULE, NAME, data_obj, USEDFORSECURITY); \
1027-
} while (0)
1024+
return _hashlib_new_impl(MODULE, NAME, DATA, USEDFORSECURITY, STRING)
10281025

10291026
/* The module-level function: new() */
10301027

@@ -1050,7 +1047,11 @@ _hashlib_new_impl(PyObject *module, const char *name, PyObject *data,
10501047
int usedforsecurity, PyObject *string)
10511048
/*[clinic end generated code: output=c01feb4ad6a6303d input=f5ec9bf1fa749d07]*/
10521049
{
1053-
CALL_HASHLIB_NEW(module, name, data, string, usedforsecurity);
1050+
PyObject *data_obj;
1051+
if (_Py_hashlib_data_argument(&data_obj, data, string) < 0) {
1052+
return NULL;
1053+
}
1054+
return _hashlib_HASH(module, name, data_obj, usedforsecurity);
10541055
}
10551056

10561057

Modules/hashlib.h

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,51 @@
33
#include "pycore_lock.h" // PyMutex
44

55
/*
6-
* Given a PyObject* obj, fill in the Py_buffer* viewp with the result
7-
* of PyObject_GetBuffer. Sets an exception and issues the erraction
8-
* on any errors, e.g. 'return NULL' or 'goto error'.
6+
* Obtain a buffer view from a buffer-like object 'obj'.
7+
*
8+
* On success, store the result in 'view' and return 0.
9+
* On error, set an exception and return -1.
910
*/
10-
#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \
11-
if (PyUnicode_Check((obj))) { \
12-
PyErr_SetString(PyExc_TypeError, \
13-
"Strings must be encoded before hashing");\
14-
erraction; \
15-
} \
16-
if (!PyObject_CheckBuffer((obj))) { \
17-
PyErr_SetString(PyExc_TypeError, \
18-
"object supporting the buffer API required"); \
19-
erraction; \
20-
} \
21-
if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \
22-
erraction; \
23-
} \
24-
if ((viewp)->ndim > 1) { \
25-
PyErr_SetString(PyExc_BufferError, \
26-
"Buffer must be single dimension"); \
27-
PyBuffer_Release((viewp)); \
28-
erraction; \
29-
} \
30-
} while(0)
11+
static inline int
12+
_Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view)
13+
{
14+
if (PyUnicode_Check(obj)) {
15+
PyErr_SetString(PyExc_TypeError,
16+
"Strings must be encoded before hashing");
17+
return -1;
18+
}
19+
if (!PyObject_CheckBuffer(obj)) {
20+
PyErr_SetString(PyExc_TypeError,
21+
"object supporting the buffer API required");
22+
return -1;
23+
}
24+
if (PyObject_GetBuffer(obj, view, PyBUF_SIMPLE) == -1) {
25+
return -1;
26+
}
27+
if (view->ndim > 1) {
28+
PyErr_SetString(PyExc_BufferError,
29+
"Buffer must be single dimension");
30+
PyBuffer_Release(view);
31+
return -1;
32+
}
33+
return 0;
34+
}
35+
36+
/*
37+
* Call _Py_hashlib_get_buffer_view() and check if it succeeded.
38+
*
39+
* On error, set an exception and execute the ERRACTION statements.
40+
*/
41+
#define GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, ERRACTION) \
42+
do { \
43+
if (_Py_hashlib_get_buffer_view(OBJ, VIEW) < 0) { \
44+
assert(PyErr_Occurred()); \
45+
ERRACTION; \
46+
} \
47+
} while (0)
3148

32-
#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \
33-
GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL)
49+
#define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \
50+
GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL)
3451

3552
/*
3653
* Helper code to synchronize access to the hash object when the GIL is

Modules/hmacmodule.c

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,42 +1259,60 @@ _hmac_compute_digest_impl(PyObject *module, PyObject *key, PyObject *msg,
12591259
}
12601260

12611261
/*
1262-
* One-shot HMAC-HASH using the given HACL_HID.
1262+
* Obtain a view for 'key' and 'msg', storing it in 'keyview' and 'msgview'.
1263+
*
1264+
* Return 0 on success; otherwise set an exception and return -1.
12631265
*
12641266
* The length of the key and message buffers must not exceed UINT32_MAX,
12651267
* lest an OverflowError is raised. The Python implementation takes care
12661268
* of dispatching to the OpenSSL implementation in this case.
12671269
*/
1268-
#define Py_HMAC_HACL_ONESHOT(HACL_HID, KEY, MSG) \
1269-
do { \
1270-
Py_buffer keyview, msgview; \
1271-
GET_BUFFER_VIEW_OR_ERROUT((KEY), &keyview); \
1272-
if (!has_uint32_t_buffer_length(&keyview)) { \
1273-
PyBuffer_Release(&keyview); \
1274-
set_invalid_key_length_error(); \
1275-
return NULL; \
1276-
} \
1277-
GET_BUFFER_VIEW_OR_ERROR((MSG), &msgview, \
1278-
PyBuffer_Release(&keyview); \
1279-
return NULL); \
1280-
if (!has_uint32_t_buffer_length(&msgview)) { \
1281-
PyBuffer_Release(&msgview); \
1282-
PyBuffer_Release(&keyview); \
1283-
set_invalid_msg_length_error(); \
1284-
return NULL; \
1285-
} \
1286-
uint8_t out[Py_hmac_## HACL_HID ##_digest_size]; \
1287-
Py_hmac_## HACL_HID ##_compute_func( \
1288-
out, \
1289-
(uint8_t *)keyview.buf, (uint32_t)keyview.len, \
1290-
(uint8_t *)msgview.buf, (uint32_t)msgview.len \
1291-
); \
1292-
PyBuffer_Release(&msgview); \
1293-
PyBuffer_Release(&keyview); \
1294-
return PyBytes_FromStringAndSize( \
1295-
(const char *)out, \
1296-
Py_hmac_## HACL_HID ##_digest_size \
1297-
); \
1270+
static int
1271+
hmac_get_buffer_views(PyObject *key, Py_buffer *keyview,
1272+
PyObject *msg, Py_buffer *msgview)
1273+
{
1274+
if (_Py_hashlib_get_buffer_view(key, keyview) < 0) {
1275+
return -1;
1276+
}
1277+
if (!has_uint32_t_buffer_length(keyview)) {
1278+
PyBuffer_Release(keyview);
1279+
set_invalid_key_length_error();
1280+
return -1;
1281+
}
1282+
if (_Py_hashlib_get_buffer_view(msg, msgview) < 0) {
1283+
PyBuffer_Release(keyview);
1284+
return -1;
1285+
}
1286+
if (!has_uint32_t_buffer_length(msgview)) {
1287+
PyBuffer_Release(msgview);
1288+
PyBuffer_Release(keyview);
1289+
set_invalid_msg_length_error();
1290+
return -1;
1291+
}
1292+
return 0;
1293+
}
1294+
1295+
/*
1296+
* One-shot HMAC-HASH using the given HACL_HID.
1297+
*/
1298+
#define HACL_HMAC_COMPUTE_NAMED_DIGEST(HACL_HID, KEY, MSG) \
1299+
do { \
1300+
Py_buffer keyview, msgview; \
1301+
if (hmac_get_buffer_views(key, &keyview, msg, &msgview) < 0) { \
1302+
return NULL; \
1303+
} \
1304+
uint8_t out[Py_hmac_## HACL_HID ##_digest_size]; \
1305+
Py_hmac_## HACL_HID ##_compute_func( \
1306+
out, \
1307+
(uint8_t *)keyview.buf, (uint32_t)keyview.len, \
1308+
(uint8_t *)msgview.buf, (uint32_t)msgview.len \
1309+
); \
1310+
PyBuffer_Release(&msgview); \
1311+
PyBuffer_Release(&keyview); \
1312+
return PyBytes_FromStringAndSize( \
1313+
(const char *)out, \
1314+
Py_hmac_## HACL_HID ##_digest_size \
1315+
); \
12981316
} while (0)
12991317

13001318
/*[clinic input]
@@ -1310,7 +1328,7 @@ static PyObject *
13101328
_hmac_compute_md5_impl(PyObject *module, PyObject *key, PyObject *msg)
13111329
/*[clinic end generated code: output=7837a4ceccbbf636 input=77a4b774c7d61218]*/
13121330
{
1313-
Py_HMAC_HACL_ONESHOT(md5, key, msg);
1331+
HACL_HMAC_COMPUTE_NAMED_DIGEST(md5, key, msg);
13141332
}
13151333

13161334
/*[clinic input]
@@ -1326,7 +1344,7 @@ static PyObject *
13261344
_hmac_compute_sha1_impl(PyObject *module, PyObject *key, PyObject *msg)
13271345
/*[clinic end generated code: output=79fd7689c83691d8 input=3b64dccc6bdbe4ba]*/
13281346
{
1329-
Py_HMAC_HACL_ONESHOT(sha1, key, msg);
1347+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha1, key, msg);
13301348
}
13311349

13321350
/*[clinic input]
@@ -1342,7 +1360,7 @@ static PyObject *
13421360
_hmac_compute_sha2_224_impl(PyObject *module, PyObject *key, PyObject *msg)
13431361
/*[clinic end generated code: output=7f21f1613e53979e input=a1a75f25f23449af]*/
13441362
{
1345-
Py_HMAC_HACL_ONESHOT(sha2_224, key, msg);
1363+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_224, key, msg);
13461364
}
13471365

13481366
/*[clinic input]
@@ -1358,7 +1376,7 @@ static PyObject *
13581376
_hmac_compute_sha2_256_impl(PyObject *module, PyObject *key, PyObject *msg)
13591377
/*[clinic end generated code: output=d4a291f7d9a82459 input=5c9ccf2df048ace3]*/
13601378
{
1361-
Py_HMAC_HACL_ONESHOT(sha2_256, key, msg);
1379+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_256, key, msg);
13621380
}
13631381

13641382
/*[clinic input]
@@ -1374,7 +1392,7 @@ static PyObject *
13741392
_hmac_compute_sha2_384_impl(PyObject *module, PyObject *key, PyObject *msg)
13751393
/*[clinic end generated code: output=f211fa26e3700c27 input=2fee2c14766af231]*/
13761394
{
1377-
Py_HMAC_HACL_ONESHOT(sha2_384, key, msg);
1395+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_384, key, msg);
13781396
}
13791397

13801398
/*[clinic input]
@@ -1390,7 +1408,7 @@ static PyObject *
13901408
_hmac_compute_sha2_512_impl(PyObject *module, PyObject *key, PyObject *msg)
13911409
/*[clinic end generated code: output=d5c20373762cecca input=3371eaac315c7864]*/
13921410
{
1393-
Py_HMAC_HACL_ONESHOT(sha2_512, key, msg);
1411+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_512, key, msg);
13941412
}
13951413

13961414
/*[clinic input]
@@ -1406,7 +1424,7 @@ static PyObject *
14061424
_hmac_compute_sha3_224_impl(PyObject *module, PyObject *key, PyObject *msg)
14071425
/*[clinic end generated code: output=a242ccac9ad9c22b input=d0ab0c7d189c3d87]*/
14081426
{
1409-
Py_HMAC_HACL_ONESHOT(sha3_224, key, msg);
1427+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_224, key, msg);
14101428
}
14111429

14121430
/*[clinic input]
@@ -1422,7 +1440,7 @@ static PyObject *
14221440
_hmac_compute_sha3_256_impl(PyObject *module, PyObject *key, PyObject *msg)
14231441
/*[clinic end generated code: output=b539dbb61af2fe0b input=f05d7b6364b35d02]*/
14241442
{
1425-
Py_HMAC_HACL_ONESHOT(sha3_256, key, msg);
1443+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_256, key, msg);
14261444
}
14271445

14281446
/*[clinic input]
@@ -1438,7 +1456,7 @@ static PyObject *
14381456
_hmac_compute_sha3_384_impl(PyObject *module, PyObject *key, PyObject *msg)
14391457
/*[clinic end generated code: output=5eb372fb5c4ffd3a input=d842d393e7aa05ae]*/
14401458
{
1441-
Py_HMAC_HACL_ONESHOT(sha3_384, key, msg);
1459+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_384, key, msg);
14421460
}
14431461

14441462
/*[clinic input]
@@ -1454,7 +1472,7 @@ static PyObject *
14541472
_hmac_compute_sha3_512_impl(PyObject *module, PyObject *key, PyObject *msg)
14551473
/*[clinic end generated code: output=154bcbf8c2eacac1 input=166fe5baaeaabfde]*/
14561474
{
1457-
Py_HMAC_HACL_ONESHOT(sha3_512, key, msg);
1475+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_512, key, msg);
14581476
}
14591477

14601478
/*[clinic input]
@@ -1470,7 +1488,7 @@ static PyObject *
14701488
_hmac_compute_blake2s_32_impl(PyObject *module, PyObject *key, PyObject *msg)
14711489
/*[clinic end generated code: output=cfc730791bc62361 input=d22c36e7fe31a985]*/
14721490
{
1473-
Py_HMAC_HACL_ONESHOT(blake2s_32, key, msg);
1491+
HACL_HMAC_COMPUTE_NAMED_DIGEST(blake2s_32, key, msg);
14741492
}
14751493

14761494
/*[clinic input]
@@ -1486,9 +1504,11 @@ static PyObject *
14861504
_hmac_compute_blake2b_32_impl(PyObject *module, PyObject *key, PyObject *msg)
14871505
/*[clinic end generated code: output=765c5c4fb9124636 input=4a35ee058d172f4b]*/
14881506
{
1489-
Py_HMAC_HACL_ONESHOT(blake2b_32, key, msg);
1507+
HACL_HMAC_COMPUTE_NAMED_DIGEST(blake2b_32, key, msg);
14901508
}
14911509

1510+
#undef HACL_HMAC_COMPUTE_NAMED_DIGEST
1511+
14921512
// --- HMAC module methods ----------------------------------------------------
14931513

14941514
static PyMethodDef hmacmodule_methods[] = {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy