Coverage Report

Created: 2025-09-01 06:47

/src/wolfssl/wolfssl/wolfcrypt/cpuid.h
Line
Count
Source (jump to first uncovered line)
1
/* cpuid.h
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
23
24
#ifndef WOLF_CRYPT_CPUID_H
25
#define WOLF_CRYPT_CPUID_H
26
27
28
#include <wolfssl/wolfcrypt/types.h>
29
30
31
#ifdef __cplusplus
32
    extern "C" {
33
#endif
34
35
#if (defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \
36
    defined(WOLFSSL_AESNI) || defined(WOLFSSL_SP_X86_64_ASM)) && \
37
    !defined(WOLFSSL_NO_ASM)
38
    #define HAVE_CPUID
39
    #define HAVE_CPUID_INTEL
40
#endif
41
#if (defined(WOLFSSL_AARCH64_BUILD) || (defined(__aarch64__) && \
42
     defined(WOLFSSL_ARMASM))) && !defined(WOLFSSL_NO_ASM)
43
    #define HAVE_CPUID
44
    #define HAVE_CPUID_AARCH64
45
#endif
46
47
#define WC_CPUID_INITIALIZER 0xffffffffU
48
typedef word32 cpuid_flags_t;
49
#if !defined(WOLFSSL_NO_ATOMICS) && !defined(SINGLE_THREADED)
50
    typedef wolfSSL_Atomic_Uint cpuid_flags_atomic_t;
51
    #define WC_CPUID_ATOMIC_INITIALIZER \
52
        WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_INITIALIZER)
53
#else
54
    typedef word32 cpuid_flags_atomic_t;
55
    #define WC_CPUID_ATOMIC_INITIALIZER WC_CPUID_INITIALIZER
56
#endif
57
58
#ifdef HAVE_CPUID_INTEL
59
60
    #define CPUID_AVX1   0x0001
61
    #define CPUID_AVX2   0x0002
62
    #define CPUID_RDRAND 0x0004
63
    #define CPUID_RDSEED 0x0008
64
    #define CPUID_BMI2   0x0010   /* MULX, RORX */
65
    #define CPUID_AESNI  0x0020
66
    #define CPUID_ADX    0x0040   /* ADCX, ADOX */
67
    #define CPUID_MOVBE  0x0080   /* Move and byte swap */
68
    #define CPUID_BMI1   0x0100   /* ANDN */
69
    #define CPUID_SHA    0x0200   /* SHA-1 and SHA-256 instructions */
70
71
    #define IS_INTEL_AVX1(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AVX1)
72
    #define IS_INTEL_AVX2(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AVX2)
73
    #define IS_INTEL_RDRAND(f)  (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDRAND)
74
    #define IS_INTEL_RDSEED(f)  (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDSEED)
75
    #define IS_INTEL_BMI2(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_BMI2)
76
    #define IS_INTEL_AESNI(f)   (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AESNI)
77
    #define IS_INTEL_ADX(f)     (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_ADX)
78
    #define IS_INTEL_MOVBE(f)   (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_MOVBE)
79
    #define IS_INTEL_BMI1(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_BMI1)
80
    #define IS_INTEL_SHA(f)     (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA)
81
82
#elif defined(HAVE_CPUID_AARCH64)
83
84
    #define CPUID_AES         0x0001    /* AES enc/dec */
85
    #define CPUID_PMULL       0x0002    /* Carryless multiplication */
86
    #define CPUID_SHA256      0x0004    /* SHA-256 digest */
87
    #define CPUID_SHA512      0x0008    /* SHA-512 digest */
88
    #define CPUID_RDM         0x0010    /* SQRDMLAH and SQRDMLSH */
89
    #define CPUID_SHA3        0x0020    /* SHA-3 digest */
90
    #define CPUID_SM3         0x0040    /* SM3 digest */
91
    #define CPUID_SM4         0x0080    /* SM4 enc/dec */
92
    #define CPUID_SB          0x0100    /* Speculation barrier */
93
94
    #define IS_AARCH64_AES(f)       (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AES)
95
    #define IS_AARCH64_PMULL(f)     (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_PMULL)
96
    #define IS_AARCH64_SHA256(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA256)
97
    #define IS_AARCH64_SHA512(f)    (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA512)
98
    #define IS_AARCH64_RDM(f)       (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDM)
99
    #define IS_AARCH64_SHA3(f)      (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA3)
100
    #define IS_AARCH64_SM3(f)       (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SM3)
101
    #define IS_AARCH64_SM4(f)       (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SM4)
102
    #define IS_AARCH64_SB(f)        (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SB)
103
104
#endif
105
106
#ifdef HAVE_CPUID
107
    cpuid_flags_t cpuid_get_flags(void);
108
109
    /* Idempotent flag getter -- fast, but return value (whether updated) is not
110
     * strictly reliable.
111
     */
112
0
    static WC_INLINE int cpuid_get_flags_ex(cpuid_flags_t *flags) {
113
0
        if (*flags == WC_CPUID_INITIALIZER) {
114
0
            *flags = cpuid_get_flags();
115
0
            return 1;
116
0
        }
117
0
        else
118
0
            return 0;
119
0
    }
Unexecuted instantiation: random.c:cpuid_get_flags_ex
Unexecuted instantiation: sha256.c:cpuid_get_flags_ex
Unexecuted instantiation: aes.c:cpuid_get_flags_ex
Unexecuted instantiation: sha512.c:cpuid_get_flags_ex
Unexecuted instantiation: wc_port.c:cpuid_get_flags_ex
Unexecuted instantiation: poly1305.c:cpuid_get_flags_ex
Unexecuted instantiation: chacha.c:cpuid_get_flags_ex
120
121
    /* Strictly race-free flag getter -- slow, but the return value is strictly
122
     * accurate.
123
     */
124
0
    static WC_INLINE int cpuid_get_flags_atomic(cpuid_flags_atomic_t *flags) {
125
0
        if (WOLFSSL_ATOMIC_LOAD(*flags) == WC_CPUID_INITIALIZER) {
126
0
            cpuid_flags_t old_cpuid_flags = WC_CPUID_INITIALIZER;
127
0
            return wolfSSL_Atomic_Uint_CompareExchange
128
0
                (flags, &old_cpuid_flags, cpuid_get_flags());
129
0
        }
130
0
        else
131
0
            return 0;
132
0
    }
Unexecuted instantiation: random.c:cpuid_get_flags_atomic
Unexecuted instantiation: sha256.c:cpuid_get_flags_atomic
Unexecuted instantiation: aes.c:cpuid_get_flags_atomic
Unexecuted instantiation: sha512.c:cpuid_get_flags_atomic
Unexecuted instantiation: wc_port.c:cpuid_get_flags_atomic
Unexecuted instantiation: poly1305.c:cpuid_get_flags_atomic
Unexecuted instantiation: chacha.c:cpuid_get_flags_atomic
133
134
135
    /* Public APIs to modify flags. */
136
    WOLFSSL_API void cpuid_select_flags(cpuid_flags_t flags);
137
    WOLFSSL_API void cpuid_set_flag(cpuid_flags_t flag);
138
    WOLFSSL_API void cpuid_clear_flag(cpuid_flags_t flag);
139
140
#endif
141
142
#ifdef __cplusplus
143
    }   /* extern "C" */
144
#endif
145
146
147
#endif /* WOLF_CRYPT_CPUID_H */