Skip to content

Commit 5c13316

Browse files
committed
add vectorized blake2s/2b kinds
Since HACL* supports vectorized blake2s/2b, we need to introduce additional discriminated types in order to use the corresponding typed states. Note that we perform both a static and a runtime tests to avoid "illegal instruction" errors due to the host CPU.
1 parent 6227892 commit 5c13316

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

Modules/hmacmodule.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ typedef enum HMAC_Hash_Kind {
144144
/* Blake family */
145145
DECL_HACL_HMAC_HASH_KIND(blake2s_32, Blake2S_32)
146146
DECL_HACL_HMAC_HASH_KIND(blake2b_32, Blake2B_32)
147+
/* Blake runtime family (should not be used statically) */
148+
DECL_HACL_HMAC_HASH_KIND(vectorized_blake2s_32, Blake2S_128)
149+
DECL_HACL_HMAC_HASH_KIND(vectorized_blake2b_32, Blake2B_256)
147150
#undef DECL_HACL_HMAC_HASH_KIND
148151
} HMAC_Hash_Kind;
149152

@@ -325,6 +328,9 @@ typedef struct hmacmodule_state {
325328
PyTypeObject *hmac_type;
326329
/* interned strings */
327330
PyObject *str_lower;
331+
332+
bool can_run_simd128;
333+
bool can_run_simd256;
328334
} hmacmodule_state;
329335

330336
static inline hmacmodule_state *
@@ -389,6 +395,67 @@ class _hmac.HMAC "HMACObject *" "clinic_state()->hmac_type"
389395
// whose length fits on 32-bit or 64-bit integers (depending on the host
390396
// machine).
391397

398+
/*
399+
* Assert that a HMAC hash kind is a static kind.
400+
*
401+
* A "static" kind is specified in the 'py_hmac_static_hinfo'
402+
* table and is always independent of the host CPUID features.
403+
*/
404+
#ifndef NDEBUG
405+
static void
406+
assert_is_static_hmac_hash_kind(HMAC_Hash_Kind kind)
407+
{
408+
switch (kind) {
409+
case Py_hmac_kind_hash_unknown: {
410+
Py_FatalError("HMAC hash kind must be a known kind");
411+
return;
412+
}
413+
case Py_hmac_kind_hmac_vectorized_blake2s_32:
414+
case Py_hmac_kind_hmac_vectorized_blake2b_32: {
415+
Py_FatalError("HMAC hash kind must not be a vectorized kind");
416+
return;
417+
}
418+
default:
419+
return;
420+
}
421+
}
422+
#else
423+
static inline void
424+
assert_is_static_hmac_hash_kind(HMAC_Hash_Kind Py_UNUSED(kind)) {}
425+
#endif
426+
427+
/*
428+
* Convert a HMAC hash static kind into a runtime kind.
429+
*
430+
* A "runtime" kind is derived from a static kind and depends
431+
* on the host CPUID features. In particular, this is the kind
432+
* that a HMAC object internally stores.
433+
*/
434+
static HMAC_Hash_Kind
435+
narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind)
436+
{
437+
switch (kind) {
438+
case Py_hmac_kind_hmac_blake2s_32: {
439+
#if HACL_CAN_COMPILE_SIMD128
440+
if (state->can_run_simd128) {
441+
return Py_hmac_kind_hmac_vectorized_blake2s_32;
442+
}
443+
#endif
444+
return kind;
445+
}
446+
case Py_hmac_kind_hmac_blake2b_32: {
447+
#if HACL_CAN_COMPILE_SIMD256
448+
if (state->can_run_simd256) {
449+
return Py_hmac_kind_hmac_vectorized_blake2b_32;
450+
}
451+
#endif
452+
return kind;
453+
}
454+
default:
455+
return kind;
456+
}
457+
}
458+
392459
/*
393460
* Handle the HACL* exit code.
394461
*
@@ -1264,7 +1331,16 @@ py_hmac_hinfo_ht_new(void)
12641331
}
12651332

12661333
for (const py_hmac_hinfo *e = py_hmac_static_hinfo; e->name != NULL; e++) {
1267-
assert(e->kind != Py_hmac_kind_hash_unknown);
1334+
/*
1335+
* The real kind of a HMAC object is obtained only once and is
1336+
* derived from the kind of the 'py_hmac_hinfo' that could be
1337+
* found by its name.
1338+
*
1339+
* Since 'vectorized_blake2{s,b}_32' depend on the runtime CPUID
1340+
* features, we should not create 'py_hmac_hinfo' entries for them.
1341+
*/
1342+
assert_is_static_hmac_hash_kind(e->kind);
1343+
12681344
py_hmac_hinfo *value = PyMem_Malloc(sizeof(py_hmac_hinfo));
12691345
if (value == NULL) {
12701346
PyErr_NoMemory();
@@ -1366,6 +1442,24 @@ hmacmodule_init_strings(hmacmodule_state *state)
13661442
return 0;
13671443
}
13681444

1445+
static void
1446+
hmacmodule_init_cpu_features(hmacmodule_state *state)
1447+
{
1448+
#if HACL_CAN_COMPILE_SIMD128
1449+
// TODO: use py_cpuid_features (gh-125022) to deduce what we want
1450+
state->can_run_simd128 = false;
1451+
#else
1452+
state->can_run_simd128 = false;
1453+
#endif
1454+
1455+
#if HACL_CAN_COMPILE_SIMD256
1456+
// TODO: use py_cpuid_features (gh-125022) to deduce what we want
1457+
state->can_run_simd256 = false;
1458+
#else
1459+
state->can_run_simd256 = false;
1460+
#endif
1461+
}
1462+
13691463
static int
13701464
hmacmodule_exec(PyObject *module)
13711465
{
@@ -1382,6 +1476,7 @@ hmacmodule_exec(PyObject *module)
13821476
if (hmacmodule_init_strings(state) < 0) {
13831477
return -1;
13841478
}
1479+
hmacmodule_init_cpu_features(state);
13851480
return 0;
13861481
}
13871482

0 commit comments

Comments
 (0)