Skip to content

Commit eefd70f

Browse files
authored
gh-136968: fortify macro usage in cryptographic modules (#136973)
Macros used in cryptographic extension modules are partially rewritten to use `static inline` functions when possible to help code completion.
1 parent 4e40f2b commit eefd70f

File tree

3 files changed

+116
-78
lines changed

3 files changed

+116
-78
lines changed

Modules/_hashopenssl.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,15 +1251,11 @@ _hashlib_HASH(_hashlibstate *state, const char *digestname, PyObject *data_obj,
12511251
return (PyObject *)self;
12521252
}
12531253

1254+
// In Python 3.19, we can remove the "STRING" argument and would also be able
1255+
// to remove the macro (or keep it as an alias for better naming) since calls
1256+
// to _hashlib_HASH_new_impl() would fit on 80 characters.
12541257
#define CALL_HASHLIB_NEW(MODULE, NAME, DATA, STRING, USEDFORSECURITY) \
1255-
do { \
1256-
PyObject *data_obj; \
1257-
if (_Py_hashlib_data_argument(&data_obj, DATA, STRING) < 0) { \
1258-
return NULL; \
1259-
} \
1260-
_hashlibstate *state = get_hashlib_state(MODULE); \
1261-
return _hashlib_HASH(state, NAME, data_obj, USEDFORSECURITY); \
1262-
} while (0)
1258+
return _hashlib_HASH_new_impl(MODULE, NAME, DATA, USEDFORSECURITY, STRING)
12631259

12641260
/* The module-level function: new() */
12651261

@@ -1285,7 +1281,12 @@ _hashlib_HASH_new_impl(PyObject *module, const char *name, PyObject *data,
12851281
int usedforsecurity, PyObject *string)
12861282
/*[clinic end generated code: output=b905aaf9840c1bbd input=c34af6c6e696d44e]*/
12871283
{
1288-
CALL_HASHLIB_NEW(module, name, data, string, usedforsecurity);
1284+
PyObject *data_obj;
1285+
if (_Py_hashlib_data_argument(&data_obj, data, string) < 0) {
1286+
return NULL;
1287+
}
1288+
_hashlibstate *state = get_hashlib_state(module);
1289+
return _hashlib_HASH(state, name, data_obj, usedforsecurity);
12891290
}
12901291

12911292

Modules/hashlib.h

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,51 @@
1212
#define HASHLIB_UNSUPPORTED_STR_ALGORITHM "unsupported hash algorithm %s"
1313

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

41-
#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \
42-
GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL)
58+
#define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \
59+
GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL)
4360

4461
/*
4562
* 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
@@ -1099,42 +1099,60 @@ _hmac_compute_digest_impl(PyObject *module, PyObject *key, PyObject *msg,
10991099
}
11001100

11011101
/*
1102-
* One-shot HMAC-HASH using the given HACL_HID.
1102+
* Obtain a view for 'key' and 'msg', storing it in 'keyview' and 'msgview'.
1103+
*
1104+
* Return 0 on success; otherwise set an exception and return -1.
11031105
*
11041106
* The length of the key and message buffers must not exceed UINT32_MAX,
11051107
* lest an OverflowError is raised. The Python implementation takes care
11061108
* of dispatching to the OpenSSL implementation in this case.
11071109
*/
1108-
#define Py_HMAC_HACL_ONESHOT(HACL_HID, KEY, MSG) \
1109-
do { \
1110-
Py_buffer keyview, msgview; \
1111-
GET_BUFFER_VIEW_OR_ERROUT((KEY), &keyview); \
1112-
if (!has_uint32_t_buffer_length(&keyview)) { \
1113-
PyBuffer_Release(&keyview); \
1114-
set_invalid_key_length_error(); \
1115-
return NULL; \
1116-
} \
1117-
GET_BUFFER_VIEW_OR_ERROR((MSG), &msgview, \
1118-
PyBuffer_Release(&keyview); \
1119-
return NULL); \
1120-
if (!has_uint32_t_buffer_length(&msgview)) { \
1121-
PyBuffer_Release(&msgview); \
1122-
PyBuffer_Release(&keyview); \
1123-
set_invalid_msg_length_error(); \
1124-
return NULL; \
1125-
} \
1126-
uint8_t out[Py_hmac_## HACL_HID ##_digest_size]; \
1127-
Py_hmac_## HACL_HID ##_compute_func( \
1128-
out, \
1129-
(uint8_t *)keyview.buf, (uint32_t)keyview.len, \
1130-
(uint8_t *)msgview.buf, (uint32_t)msgview.len \
1131-
); \
1132-
PyBuffer_Release(&msgview); \
1133-
PyBuffer_Release(&keyview); \
1134-
return PyBytes_FromStringAndSize( \
1135-
(const char *)out, \
1136-
Py_hmac_## HACL_HID ##_digest_size \
1137-
); \
1110+
static int
1111+
hmac_get_buffer_views(PyObject *key, Py_buffer *keyview,
1112+
PyObject *msg, Py_buffer *msgview)
1113+
{
1114+
if (_Py_hashlib_get_buffer_view(key, keyview) < 0) {
1115+
return -1;
1116+
}
1117+
if (!has_uint32_t_buffer_length(keyview)) {
1118+
PyBuffer_Release(keyview);
1119+
set_invalid_key_length_error();
1120+
return -1;
1121+
}
1122+
if (_Py_hashlib_get_buffer_view(msg, msgview) < 0) {
1123+
PyBuffer_Release(keyview);
1124+
return -1;
1125+
}
1126+
if (!has_uint32_t_buffer_length(msgview)) {
1127+
PyBuffer_Release(msgview);
1128+
PyBuffer_Release(keyview);
1129+
set_invalid_msg_length_error();
1130+
return -1;
1131+
}
1132+
return 0;
1133+
}
1134+
1135+
/*
1136+
* One-shot HMAC-HASH using the given HACL_HID.
1137+
*/
1138+
#define HACL_HMAC_COMPUTE_NAMED_DIGEST(HACL_HID, KEY, MSG) \
1139+
do { \
1140+
Py_buffer keyview, msgview; \
1141+
if (hmac_get_buffer_views(key, &keyview, msg, &msgview) < 0) { \
1142+
return NULL; \
1143+
} \
1144+
uint8_t out[Py_hmac_## HACL_HID ##_digest_size]; \
1145+
Py_hmac_## HACL_HID ##_compute_func( \
1146+
out, \
1147+
(uint8_t *)keyview.buf, (uint32_t)keyview.len, \
1148+
(uint8_t *)msgview.buf, (uint32_t)msgview.len \
1149+
); \
1150+
PyBuffer_Release(&msgview); \
1151+
PyBuffer_Release(&keyview); \
1152+
return PyBytes_FromStringAndSize( \
1153+
(const char *)out, \
1154+
Py_hmac_## HACL_HID ##_digest_size \
1155+
); \
11381156
} while (0)
11391157

11401158
/*[clinic input]
@@ -1150,7 +1168,7 @@ static PyObject *
11501168
_hmac_compute_md5_impl(PyObject *module, PyObject *key, PyObject *msg)
11511169
/*[clinic end generated code: output=7837a4ceccbbf636 input=77a4b774c7d61218]*/
11521170
{
1153-
Py_HMAC_HACL_ONESHOT(md5, key, msg);
1171+
HACL_HMAC_COMPUTE_NAMED_DIGEST(md5, key, msg);
11541172
}
11551173

11561174
/*[clinic input]
@@ -1166,7 +1184,7 @@ static PyObject *
11661184
_hmac_compute_sha1_impl(PyObject *module, PyObject *key, PyObject *msg)
11671185
/*[clinic end generated code: output=79fd7689c83691d8 input=3b64dccc6bdbe4ba]*/
11681186
{
1169-
Py_HMAC_HACL_ONESHOT(sha1, key, msg);
1187+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha1, key, msg);
11701188
}
11711189

11721190
/*[clinic input]
@@ -1182,7 +1200,7 @@ static PyObject *
11821200
_hmac_compute_sha2_224_impl(PyObject *module, PyObject *key, PyObject *msg)
11831201
/*[clinic end generated code: output=7f21f1613e53979e input=a1a75f25f23449af]*/
11841202
{
1185-
Py_HMAC_HACL_ONESHOT(sha2_224, key, msg);
1203+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_224, key, msg);
11861204
}
11871205

11881206
/*[clinic input]
@@ -1198,7 +1216,7 @@ static PyObject *
11981216
_hmac_compute_sha2_256_impl(PyObject *module, PyObject *key, PyObject *msg)
11991217
/*[clinic end generated code: output=d4a291f7d9a82459 input=5c9ccf2df048ace3]*/
12001218
{
1201-
Py_HMAC_HACL_ONESHOT(sha2_256, key, msg);
1219+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_256, key, msg);
12021220
}
12031221

12041222
/*[clinic input]
@@ -1214,7 +1232,7 @@ static PyObject *
12141232
_hmac_compute_sha2_384_impl(PyObject *module, PyObject *key, PyObject *msg)
12151233
/*[clinic end generated code: output=f211fa26e3700c27 input=2fee2c14766af231]*/
12161234
{
1217-
Py_HMAC_HACL_ONESHOT(sha2_384, key, msg);
1235+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_384, key, msg);
12181236
}
12191237

12201238
/*[clinic input]
@@ -1230,7 +1248,7 @@ static PyObject *
12301248
_hmac_compute_sha2_512_impl(PyObject *module, PyObject *key, PyObject *msg)
12311249
/*[clinic end generated code: output=d5c20373762cecca input=3371eaac315c7864]*/
12321250
{
1233-
Py_HMAC_HACL_ONESHOT(sha2_512, key, msg);
1251+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha2_512, key, msg);
12341252
}
12351253

12361254
/*[clinic input]
@@ -1246,7 +1264,7 @@ static PyObject *
12461264
_hmac_compute_sha3_224_impl(PyObject *module, PyObject *key, PyObject *msg)
12471265
/*[clinic end generated code: output=a242ccac9ad9c22b input=d0ab0c7d189c3d87]*/
12481266
{
1249-
Py_HMAC_HACL_ONESHOT(sha3_224, key, msg);
1267+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_224, key, msg);
12501268
}
12511269

12521270
/*[clinic input]
@@ -1262,7 +1280,7 @@ static PyObject *
12621280
_hmac_compute_sha3_256_impl(PyObject *module, PyObject *key, PyObject *msg)
12631281
/*[clinic end generated code: output=b539dbb61af2fe0b input=f05d7b6364b35d02]*/
12641282
{
1265-
Py_HMAC_HACL_ONESHOT(sha3_256, key, msg);
1283+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_256, key, msg);
12661284
}
12671285

12681286
/*[clinic input]
@@ -1278,7 +1296,7 @@ static PyObject *
12781296
_hmac_compute_sha3_384_impl(PyObject *module, PyObject *key, PyObject *msg)
12791297
/*[clinic end generated code: output=5eb372fb5c4ffd3a input=d842d393e7aa05ae]*/
12801298
{
1281-
Py_HMAC_HACL_ONESHOT(sha3_384, key, msg);
1299+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_384, key, msg);
12821300
}
12831301

12841302
/*[clinic input]
@@ -1294,7 +1312,7 @@ static PyObject *
12941312
_hmac_compute_sha3_512_impl(PyObject *module, PyObject *key, PyObject *msg)
12951313
/*[clinic end generated code: output=154bcbf8c2eacac1 input=166fe5baaeaabfde]*/
12961314
{
1297-
Py_HMAC_HACL_ONESHOT(sha3_512, key, msg);
1315+
HACL_HMAC_COMPUTE_NAMED_DIGEST(sha3_512, key, msg);
12981316
}
12991317

13001318
/*[clinic input]
@@ -1310,7 +1328,7 @@ static PyObject *
13101328
_hmac_compute_blake2s_32_impl(PyObject *module, PyObject *key, PyObject *msg)
13111329
/*[clinic end generated code: output=cfc730791bc62361 input=d22c36e7fe31a985]*/
13121330
{
1313-
Py_HMAC_HACL_ONESHOT(blake2s_32, key, msg);
1331+
HACL_HMAC_COMPUTE_NAMED_DIGEST(blake2s_32, key, msg);
13141332
}
13151333

13161334
/*[clinic input]
@@ -1326,9 +1344,11 @@ static PyObject *
13261344
_hmac_compute_blake2b_32_impl(PyObject *module, PyObject *key, PyObject *msg)
13271345
/*[clinic end generated code: output=765c5c4fb9124636 input=4a35ee058d172f4b]*/
13281346
{
1329-
Py_HMAC_HACL_ONESHOT(blake2b_32, key, msg);
1347+
HACL_HMAC_COMPUTE_NAMED_DIGEST(blake2b_32, key, msg);
13301348
}
13311349

1350+
#undef HACL_HMAC_COMPUTE_NAMED_DIGEST
1351+
13321352
// --- HMAC module methods ----------------------------------------------------
13331353

13341354
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