@@ -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
331337static 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+
13771470static int
13781471hmacmodule_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