Skip to content

Commit

Permalink
Reimplement detection of CPU features, Don't use Cpuid
Browse files Browse the repository at this point in the history
  • Loading branch information
Julow committed Apr 28, 2020
1 parent d241360 commit 96c057d
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 48 deletions.
4 changes: 2 additions & 2 deletions src/dune
@@ -1,13 +1,13 @@
(library
(name mirage_crypto)
(public_name mirage-crypto)
(libraries cstruct cpuid)
(libraries cstruct)
(private_modules ccm cipher_block cipher_stream hash native uncommon)
(c_names misc misc_sse
md5 sha1 sha256 sha512 hash_stubs
aes_generic aes_aesni ghash_generic ghash_pclmul
des_generic
entropy_cpu_stubs)
entropy_cpu_stubs detect_cpu_features)
(c_flags (:standard) (:include cflags.sexp)))

(include_subdirs unqualified)
Expand Down
8 changes: 2 additions & 6 deletions src/native.ml
Expand Up @@ -91,11 +91,7 @@ external blit : buffer -> off -> buffer -> off -> size -> unit = "caml_blit_bigs

external misc_mode : unit -> int = "mc_misc_mode" [@@noalloc]

external _set_aesni_supported : bool -> unit = "mc_aesni_set_supported" [@@noalloc]
external _set_pclmul_supported : bool -> unit = "mc_pclmul_set_supported" [@@noalloc]
external _set_sse_supported : bool -> unit = "mc_sse_set_supported" [@@noalloc]
external _detect_cpu_features : unit -> unit = "mc_detect_cpu_features" [@@noalloc]

let () =
if Cpuid.supports [`SSSE3] = Ok true then _set_sse_supported true;
if Cpuid.supports [`AES] = Ok true then _set_aesni_supported true;
if Cpuid.supports [`PCLMULQDQ] = Ok true then _set_pclmul_supported true
_detect_cpu_features ()
20 changes: 6 additions & 14 deletions src/native/aes_aesni.c
Expand Up @@ -338,26 +338,18 @@ static inline void _mc_aesni_dec_blocks (const uint8_t *src, uint8_t *dst, const

#endif /* __mc_ACCELERATE__ */

static int _aesni_supported = 0;

CAMLprim value
mc_aesni_set_supported (value s) {
_aesni_supported = Bool_val(s);
return Val_unit;
}

CAMLprim value
mc_aes_rk_size (value rounds) {
value s;
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
s = mc_aes_rk_size_generic(rounds),
s = Val_int (_mc_aesni_rk_size (Int_val (rounds))))
return s;
}

CAMLprim value
mc_aes_derive_e_key (value key, value off1, value rk, value rounds) {
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
mc_aes_derive_e_key_generic(key, off1, rk, rounds),
_mc_aesni_derive_e_key (_ba_uint8_off (key, off1),
_ba_uint8 (rk),
Expand All @@ -367,7 +359,7 @@ mc_aes_derive_e_key (value key, value off1, value rk, value rounds) {

CAMLprim value
mc_aes_derive_d_key (value key, value off1, value kr, value rounds, value rk) {
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
mc_aes_derive_d_key_generic(key, off1, kr, rounds, rk),
_mc_aesni_derive_d_key (_ba_uint8_off (key, off1),
_ba_uint8 (kr),
Expand All @@ -378,7 +370,7 @@ mc_aes_derive_d_key (value key, value off1, value kr, value rounds, value rk) {

CAMLprim value
mc_aes_enc (value src, value off1, value dst, value off2, value rk, value rounds, value blocks) {
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
mc_aes_enc_generic(src, off1, dst, off2, rk, rounds, blocks),
_mc_aesni_enc_blocks ( _ba_uint8_off (src, off1),
_ba_uint8_off (dst, off2),
Expand All @@ -390,7 +382,7 @@ mc_aes_enc (value src, value off1, value dst, value off2, value rk, value rounds

CAMLprim value
mc_aes_dec (value src, value off1, value dst, value off2, value rk, value rounds, value blocks) {
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
mc_aes_dec_generic(src, off1, dst, off2, rk, rounds, blocks),
_mc_aesni_dec_blocks ( _ba_uint8_off (src, off1),
_ba_uint8_off (dst, off2),
Expand All @@ -402,7 +394,7 @@ mc_aes_dec (value src, value off1, value dst, value off2, value rk, value rounds

CAMLprim value mc_aes_mode (__unit ()) {
value enabled = 0;
_mc_switch_accel(_aesni_supported,
_mc_switch_accel(aesni,
enabled = 0,
enabled = 1)
return Val_int (enabled);
Expand Down
32 changes: 32 additions & 0 deletions src/native/detect_cpu_features.c
@@ -0,0 +1,32 @@
#include "mirage_crypto.h"

#ifdef __mc_ACCELERATE__

#include <cpuid.h>

struct _mc_cpu_features mc_detected_cpu_features = { 0 };

CAMLprim value
mc_detect_cpu_features (__unit ()) {
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;

if (__get_cpuid(1, &eax, &ebx, &ecx, &edx))
{
if (ecx & bit_PCLMUL)
mc_detected_cpu_features.pclmul = 1;
if (ecx & bit_SSSE3)
mc_detected_cpu_features.ssse3 = 1;
if (ecx & bit_AES)
mc_detected_cpu_features.aesni = 1;
}
return Val_unit;
}

#else /* __mc_ACCELERATE__ */

CAMLprim value
mc_detect_cpu_features (__unit ()) {
return Val_unit;
}

#endif /* __mc_ACCELERATE__ */
16 changes: 4 additions & 12 deletions src/native/ghash_pclmul.c
Expand Up @@ -188,32 +188,24 @@ static inline void __ghash (__m128i *m, __m128i hash[1], const __m128i *src, siz

#endif /* __mc_ACCELERATE__ */

static int _pclmul_supported = 0;

CAMLprim value
mc_pclmul_set_supported (value s) {
_pclmul_supported = Bool_val(s);
return Val_unit;
}

CAMLprim value mc_ghash_key_size (__unit ()) {
value s;
_mc_switch_accel(_pclmul_supported,
_mc_switch_accel(pclmul,
s = mc_ghash_key_size_generic(Val_unit),
s = Val_int (__keys * 16))
return s;
}

CAMLprim value mc_ghash_init_key (value key, value off, value m) {
_mc_switch_accel(_pclmul_supported,
_mc_switch_accel(pclmul,
mc_ghash_init_key_generic(key, off, m),
__derive ((__m128i *) _ba_uint8_off (key, off), (__m128i *) Bp_val (m)))
return Val_unit;
}

CAMLprim value
mc_ghash (value k, value hash, value src, value off, value len) {
_mc_switch_accel(_pclmul_supported,
_mc_switch_accel(pclmul,
mc_ghash_generic(k, hash, src, off, len),
__ghash ( (__m128i *) Bp_val (k), (__m128i *) Bp_val (hash),
(__m128i *) _ba_uint8_off (src, off), Int_val (len) ))
Expand All @@ -222,7 +214,7 @@ mc_ghash (value k, value hash, value src, value off, value len) {

CAMLprim value mc_ghash_mode (__unit ()) {
value enabled = 0;
_mc_switch_accel(_pclmul_supported,
_mc_switch_accel(pclmul,
enabled = 0,
enabled = 1)
return Val_int (enabled);
Expand Down
15 changes: 12 additions & 3 deletions src/native/mirage_crypto.h
Expand Up @@ -14,13 +14,22 @@

#ifdef __mc_ACCELERATE__

#define _mc_switch_accel(SUPPORTED, GENERIC_CALL, ACCELERATED_CALL) \
if (!(SUPPORTED)) { GENERIC_CALL; } \
struct _mc_cpu_features {
int aesni;
int pclmul;
int ssse3;
};

/* Supported accelerations */
extern struct _mc_cpu_features mc_detected_cpu_features;

#define _mc_switch_accel(FEATURE, GENERIC_CALL, ACCELERATED_CALL) \
if (!(mc_detected_cpu_features.FEATURE)) { GENERIC_CALL; } \
else { ACCELERATED_CALL; }

#else /* __mc_ACCELERATE__ */

#define _mc_switch_accel(_SUPPORTED, GENERIC_CALL, _ACCELERATED_CALL) \
#define _mc_switch_accel(_FEATURE, GENERIC_CALL, _ACCELERATED_CALL) \
GENERIC_CALL;

#endif /* __mc_ACCELERATE__ */
Expand Down
14 changes: 3 additions & 11 deletions src/native/misc_sse.c
Expand Up @@ -31,25 +31,17 @@ static inline void _mc_count_16_be_4 (uint64_t *init, uint64_t *dst, size_t bloc

#endif /* __mc_ACCELERATE__ */

static int _sse_supported = 0;

CAMLprim value
mc_sse_set_supported (value s) {
_sse_supported = Bool_val(s);
return Val_unit;
}

CAMLprim value
mc_xor_into (value b1, value off1, value b2, value off2, value n) {
_mc_switch_accel(_sse_supported,
_mc_switch_accel(ssse3,
mc_xor_into_generic(b1, off1, b2, off2, n),
xor_into (_ba_uint8_off (b1, off1), _ba_uint8_off (b2, off2), Int_val (n)))
return Val_unit;
}

#define __export_counter(name, f) \
CAMLprim value name (value ctr, value dst, value off, value blocks) { \
_mc_switch_accel(_sse_supported, \
_mc_switch_accel(ssse3, \
name##_generic (ctr, dst, off, blocks), \
f ( (uint64_t*) Bp_val (ctr), \
(uint64_t*) _ba_uint8_off (dst, off), Long_val (blocks) )) \
Expand All @@ -60,7 +52,7 @@ __export_counter(mc_count_16_be_4, _mc_count_16_be_4)

CAMLprim value mc_misc_mode (__unit ()) {
value enabled = 0;
_mc_switch_accel(_sse_supported,
_mc_switch_accel(ssse3,
enabled = 0,
enabled = 1)
return Val_int (enabled);
Expand Down

0 comments on commit 96c057d

Please sign in to comment.