@@ -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
330336static 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+
13691463static int
13701464hmacmodule_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