Skip to content

Commit ba828fd

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 620c84d commit ba828fd

File tree

1 file changed

+95
-1
lines changed

1 file changed

+95
-1
lines changed

Modules/hmacmodule.c

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

@@ -326,6 +329,9 @@ typedef struct hmacmodule_state {
326329
PyTypeObject *hmac_type;
327330
/* interned strings */
328331
PyObject *str_lower;
332+
333+
bool can_run_simd128;
334+
bool can_run_simd256;
329335
} hmacmodule_state;
330336

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

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

12691336
for (const py_hmac_hinfo *e = py_hmac_static_hinfo; e->name != NULL; e++) {
1270-
assert(e->kind != Py_hmac_kind_hash_unknown);
1337+
/*
1338+
* The real kind of a HMAC object is obtained only once and is
1339+
* derived from the kind of the 'py_hmac_hinfo' that could be
1340+
* found by its name. Since 'vectorized_blake2{s,b}_32' depend
1341+
* depend on the runtime CPUID features, we do not allow a static
1342+
* 'py_hmac_hinfo' entry to be created for them.
1343+
*/
1344+
assert_is_static_hmac_hash_kind(e->kind);
1345+
12711346
py_hmac_hinfo *value = PyMem_Malloc(sizeof(py_hmac_hinfo));
12721347
if (value == NULL) {
12731348
PyErr_NoMemory();
@@ -1374,6 +1449,24 @@ hmacmodule_init_strings(hmacmodule_state *state)
13741449
return 0;
13751450
}
13761451

1452+
static void
1453+
hmacmodule_init_cpu_features(hmacmodule_state *state)
1454+
{
1455+
#if HACL_CAN_COMPILE_SIMD128
1456+
// TODO: use py_cpuid_features (gh-125022) to deduce what we want
1457+
state->can_run_simd128 = false;
1458+
#else
1459+
state->can_run_simd128 = false;
1460+
#endif
1461+
1462+
#if HACL_CAN_COMPILE_SIMD256
1463+
// TODO: use py_cpuid_features (gh-125022) to deduce what we want
1464+
state->can_run_simd128 = false;
1465+
#else
1466+
state->can_run_simd128 = false;
1467+
#endif
1468+
}
1469+
13771470
static int
13781471
hmacmodule_exec(PyObject *module)
13791472
{
@@ -1390,6 +1483,7 @@ hmacmodule_exec(PyObject *module)
13901483
if (hmacmodule_init_strings(state) < 0) {
13911484
return -1;
13921485
}
1486+
hmacmodule_init_cpu_features(state);
13931487
return 0;
13941488
}
13951489

0 commit comments

Comments
 (0)