1# Detect mingw, since some versions throw a warning with the -fPIC option 2# (which would be caught as an error in our case with -Werror) 3# The ELF PIE related hardening flags are also non sense for Windows 4MINGW := $(shell $(CROSS_COMPILE)$(CC) -dumpmachine 2>&1 | grep -v mingw) 5# Detect Mac OS compilers: these usually don't like ELF pie related flags ... 6APPLE := $(shell $(CROSS_COMPILE)$(CC) -dumpmachine 2>&1 | grep -v apple) 7SYS_ROOT := 8ifneq ($(MINGW),) 9 FPIC_CFLAG=-fPIC 10 ifneq ($(APPLE),) 11 FPIE_CFLAG=-fPIE 12 FPIE_LDFLAGS=-pie -Wl,-z,relro,-z,now 13 endif 14endif 15 16ifeq ($(APPLE),) 17 SYS_ROOT_PATH := $(shell xcode-select --print-path) 18 ifneq ($(SYS_ROOT_PATH),) 19 SYS_ROOT_PATH := $(SYS_ROOT_PATH)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk 20 SYS_ROOT := --sysroot=$(SYS_ROOT_PATH) 21 $(info Using MacOS SDK $(SYS_ROOT_PATH)) 22 endif 23endif 24 25# NOTE: with mingw, FORTIFY_SOURCE=2 must be used 26# in conjuction with stack-protector as check functions 27# are implemented in libssp 28STACK_PROT_FLAG=-fstack-protector-strong 29FORTIFY_FLAGS=-D_FORTIFY_SOURCE=2 30 31# The first goal here is to define a meaningful set of CFLAGS based on compiler, 32# debug mode, expected word size (16, 32, 64), etc. Those are then used to 33# define two differents kinds of CFLAGS we will use for building our library 34# (LIB_CFLAGS) and binaries (BIN_CFLAGS) objects. 35 36# Detect if we are using clang or gcc 37CLANG := $(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | grep clang) 38 39ifneq ($(CLANG),) 40 # get clang version e.g. 14.1.3 41 CLANG_VERSION := $(shell $(CROSS_COMPILE)$(CC) -dumpversion) 42 # convert to single number e.g. 14 * 100 + 1 43 CLANG_VERSION := $(shell echo $(CLANG_VERSION) | cut -f1-2 -d. | sed -e 's/\./*100+/g') 44 # Calculate value - e.g. 1401 45 CLANG_VERSION := $(shell echo $$(($(CLANG_VERSION)))) 46 # Comparison results (true if true, empty if false) 47 CLANG_VERSION_GTE_12 := $(shell [ $(CLANG_VERSION) -ge 1200 ] && echo true) 48 CLANG_VERSION_GTE_13 := $(shell [ $(CLANG_VERSION) -ge 1300 ] && echo true) 49 CLANG_VERSION_GTE_16 := $(shell [ $(CLANG_VERSION) -ge 1600 ] && echo true) 50 CLANG_VERSION_GTE_17 := $(shell [ $(CLANG_VERSION) -ge 1700 ] && echo true) 51endif 52 53# Default warning flags 54# -Werror: treat warnings as errors 55# 56# Pedantic mode: enable more warnings 57# -Wshadow: warn the user if a variable declaration shadows one from a parent context 58# -Wdouble-promotion: warn about implicit conversion from float to double 59# -Wformat=2: warn about format string vulnerabilities 60# -fno-common: disallow global variables with same name and type 61# -Wconversion: warn about implicit conversion 62# -Wformat-security: warn about format string vulnerabilities 63WARNING_CFLAGS = -Werror 64ifeq ($(PEDANTIC),1) 65 WARNING_CFLAGS += -Wshadow -Wdouble-promotion -Wformat=2 -fno-common -Wconversion -Wformat-security 66endif 67 68# Disable certain warnings: 69# -Wno-unused-parameter: commonly a false positive. Functions may be required to have a certain signature. 70# -Wno-declaration-after-statement: our C standard supports declaration after statements 71WARNING_CFLAGS += -Wno-unused-parameter -Wno-declaration-after-statement 72 73# When compiler is *explicitly* set to clang, use its -Weverything option by 74# default but disable the sepcific options we cannot support: 75# 76# -Wno-reserved-id-macro: our header files use __XXX___ protection macros. 77# -Wno-padded: padding warnings 78# -Wno-packed: warning about packed structure we want to keep that way 79# -Wno-covered-switch-default 80# -Wno-used-but-marked-unused 81# 82ifneq ($(CLANG),) 83 WARNING_CFLAGS += -Weverything \ 84 -Wno-reserved-id-macro -Wno-padded \ 85 -Wno-packed -Wno-covered-switch-default \ 86 -Wno-used-but-marked-unused -Wno-switch-enum 87 # Add warnings if we are in pedantic mode 88 ifeq ($(PEDANTIC),1) 89 WARNING_CFLAGS += -Walloca -Wcast-qual -Wnull-dereference -Wstack-protector -Wvla -Warray-bounds -Warray-bounds-pointer-arithmetic -Wassign-enum -Wbad-function-cast -Wconditional-uninitialized -Wfloat-equal -Wformat-type-confusion -Widiomatic-parentheses -Wimplicit-fallthrough -Wloop-analysis -Wpointer-arith -Wshift-sign-overflow -Wshorten-64-to-32 -Wtautological-constant-in-range-compare -Wunreachable-code-aggressive -Wthread-safety -Wthread-safety-beta -Wcomma 90 endif 91 ifeq ($(CLANG_VERSION_GTE_13), true) 92 # We have to do this because the '_' prefix seems now reserved to builtins 93 WARNING_CFLAGS += -Wno-reserved-identifier 94 endif 95 ifeq ($(CLANG_VERSION_GTE_16), true) 96 # NOTE: XXX: this is really a shame to remove this, but 97 # we have to wait until this is less sensitive and false positive 98 # prone to use it! 99 WARNING_CFLAGS += -Wno-unsafe-buffer-usage 100 endif 101else 102 WARNING_CFLAGS += -W -Wextra -Wall -Wunreachable-code 103 # Add warnings if we are in pedantic mode 104 ifeq ($(PEDANTIC),1) 105 WARNING_CFLAGS += -Wpedantic -Wformat-overflow=2 -Wformat-truncation=2 -Wnull-dereference -Wstack-protector -Wtrampolines -Walloca -Wvla -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wshift-overflow=2 -Wcast-qual -Wstringop-overflow=4 -Warith-conversion -Wlogical-op -Wduplicated-cond -Wduplicated-branches -Wformat-signedness -Wstrict-overflow=2 -Wundef -Wstrict-prototypes -Wswitch-default -Wcast-align=strict -Wjump-misses-init 106 endif 107endif 108 109ifeq ($(WNOERROR), 1) 110 # Sometimes "-Werror" might be too much, this can be overriden 111 WARNING_CFLAGS := $(subst -Werror,,$(WARNING_CFLAGS)) 112endif 113 114# If the user has overridden the CFLAGS or LDFLAGS, let's detect it 115# and adapt our compilation process 116ifdef CFLAGS 117USER_DEFINED_CFLAGS = $(CFLAGS) 118endif 119ifdef LDFLAGS 120USER_DEFINED_LDFLAGS = $(LDFLAGS) 121endif 122 123CFLAGS ?= $(WARNING_CFLAGS) $(SYS_ROOT) -pedantic -fno-builtin -std=c99 \ 124 $(FORTIFY_FLAGS) $(STACK_PROT_FLAG) -O3 125LDFLAGS ?= 126 127# Default AR and RANLIB if not overriden by user 128AR ?= ar 129RANLIB ?= ranlib 130# Default AR flags and RANLIB flags if not overriden by user 131AR_FLAGS ?= rcs 132RANLIB_FLAGS ?= 133 134# Our debug flags 135DEBUG_CFLAGS = -DDEBUG -O -g 136 137ifeq ($(VERBOSE_INNER_VALUES),1) 138CFLAGS += -DVERBOSE_INNER_VALUES 139endif 140 141# Default all and clean target that will be expanded 142# later in the Makefile 143all: 144clean: 145 146debug: CFLAGS += $(DEBUG_CFLAGS) 147debug: clean all 148 149# Force 64-bit word size 15064: CFLAGS += -DWORDSIZE=64 15164: clean all 152debug64: CFLAGS += -DWORDSIZE=64 $(DEBUG_CFLAGS) 153debug64: clean all 154 155# Force 32-bit word size 15632: CFLAGS += -DWORDSIZE=32 15732: clean all 158debug32: CFLAGS += -DWORDSIZE=32 $(DEBUG_CFLAGS) 159debug32: clean all 160 161# Force 16-bit word size 16216: CFLAGS += -DWORDSIZE=16 16316: clean all 164debug16: CFLAGS += -DWORDSIZE=16 $(DEBUG_CFLAGS) 165debug16: clean all 166 167# Force to compile with 64-bit arch 168force_arch64: CFLAGS += -m64 169force_arch64: clean all 170 171# Force to compile with 32-bit arch 172force_arch32: CFLAGS += -m32 173force_arch32: clean all 174 175# By default, we use an stdlib 176ifneq ($(LIBECC_NOSTDLIB),1) 177CFLAGS += -DWITH_STDLIB 178endif 179 180# Let's now define the two kinds of CFLAGS we will use for building our 181# library (LIB_CFLAGS) and binaries (BIN_CFLAGS) objects. 182# If the user has not overriden the CFLAGS, we add the usual gcc/clang 183# flags to produce binaries compatible with hardening technologies. 184ifndef USER_DEFINED_CFLAGS 185BIN_CFLAGS ?= $(CFLAGS) $(FPIE_CFLAG) -MMD -MP 186LIB_CFLAGS ?= $(CFLAGS) $(FPIC_CFLAG) -MMD -MP -ffreestanding 187else 188BIN_CFLAGS ?= $(USER_DEFINED_CFLAGS) 189LIB_CFLAGS ?= $(USER_DEFINED_CFLAGS) 190endif 191ifndef USER_DEFINED_LDFLAGS 192BIN_LDFLAGS ?= $(LDFLAGS) $(FPIE_LDFLAGS) 193else 194BIN_LDFLAGS ?= $(USER_DEFINED_LDFLAGS) 195endif 196 197# If the user wants to add extra flags to the existing flags, 198# check it and add them 199ifdef EXTRA_LIB_CFLAGS 200LIB_CFLAGS += $(EXTRA_LIB_CFLAGS) 201endif 202ifdef EXTRA_LIB_DYN_LDFLAGS 203LIB_DYN_LDFLAGS += $(EXTRA_LIB_DYN_LDFLAGS) 204endif 205ifdef EXTRA_BIN_CFLAGS 206BIN_CFLAGS += $(EXTRA_BIN_CFLAGS) 207endif 208ifdef EXTRA_BIN_LDFLAGS 209BIN_LDFLAGS += $(EXTRA_BIN_LDFLAGS) 210endif 211ifdef EXTRA_CFLAGS 212CFLAGS += $(EXTRA_CFLAGS) 213endif 214ifdef EXTRA_LDFLAGS 215LDFLAGS += $(EXTRA_LDFLAGS) 216endif 217 218# Add the include folder 219LIBECC_INCLUDE_FOLDER = include/ 220LIB_CFLAGS += -I$(LIBECC_INCLUDE_FOLDER) 221BIN_CFLAGS += -I$(LIBECC_INCLUDE_FOLDER) 222 223# Static libraries to produce or link to 224LIBARITH = $(BUILD_DIR)/libarith.a 225LIBEC = $(BUILD_DIR)/libec.a 226LIBSIGN = $(BUILD_DIR)/libsign.a 227 228# Compile dynamic libraries if the user asked to 229ifeq ($(WITH_DYNAMIC_LIBS),1) 230# Dynamic libraries to produce or link to 231LIBARITH_DYN = $(BUILD_DIR)/libarith.so 232LIBEC_DYN = $(BUILD_DIR)/libec.so 233LIBSIGN_DYN = $(BUILD_DIR)/libsign.so 234# The ld flags to generate shared librarie 235ifeq ($(APPLE),) 236LIB_DYN_LDFLAGS ?= -shared -Wl,-undefined,dynamic_lookup 237else 238LIB_DYN_LDFLAGS ?= -shared -Wl,-z,relro,-z,now 239endif 240endif 241 242# Do we want to use blinding to secure signature against some side channels? 243ifeq ($(BLINDING),1) 244CFLAGS += -DUSE_SIG_BLINDING 245endif 246 247# Use complete formulas for point addition and doubling 248# NOTE: complete formulas are used as default since they are 249# more resilient against side channel attacks and they do not 250# have a major performance impact 251ifeq ($(COMPLETE),0) 252CFLAGS += -DNO_USE_COMPLETE_FORMULAS 253endif 254 255# Force Double and Add always usage 256ifeq ($(ADALWAYS), 1) 257CFLAGS += -DUSE_DOUBLE_ADD_ALWAYS 258endif 259ifeq ($(ADALWAYS), 0) 260CFLAGS += -DUSE_MONTY_LADDER 261endif 262 263# Force Montgomery Ladder always usage 264ifeq ($(LADDER), 1) 265CFLAGS += -DUSE_MONTY_LADDER 266endif 267ifeq ($(LADDER), 0) 268CFLAGS += -DUSE_DOUBLE_ADD_ALWAYS 269endif 270 271# Force small stack usage 272ifeq ($(SMALLSTACK), 1) 273CFLAGS += -DUSE_SMALL_STACK 274endif 275 276# Are we sure we will not execute known 277# vectors self tests? 278ifeq ($(NOKNOWNTESTS), 1) 279CFLAGS += -DNO_KNOWN_VECTORS 280endif 281 282# Specific version for fuzzing with Cryptofuzz 283# Allow raw signature and verification APIs 284# which is DANGEROUS. Do not activate in production 285# mode! 286ifeq ($(CRYPTOFUZZ), 1) 287CFLAGS += -DUSE_CRYPTOFUZZ 288endif 289 290ifeq ($(ASSERT_PRINT), 1) 291CFLAGS += -DUSE_ASSERT_PRINT 292endif 293 294# By default, we want to catch all unused functions return values by 295# triggering a warning. We deactivate this is we are asked to by the user. 296ifneq ($(NO_WARN_UNUSED_RET), 1) 297CFLAGS += -DUSE_WARN_UNUSED_RET 298endif 299 300# Do we want to use clang or gcc sanitizers? 301ifeq ($(USE_SANITIZERS),1) 302CFLAGS += -fsanitize=undefined -fsanitize=address -fsanitize=leak 303 ifneq ($(CLANG),) 304 # Clang version < 12 do not support unsigned-shift-base 305 ifeq ($(CLANG_VERSION_GTE_12), true) 306 CFLAGS += -fsanitize=integer -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base 307 endif 308 endif 309endif 310 311# Do we want to use the ISO14888-3 version of the 312# ECRDSA algorithm with discrepancies from the Russian 313# RFC references? 314ifeq ($(USE_ISO14888_3_ECRDSA),1) 315CFLAGS += -DUSE_ISO14888_3_ECRDSA 316endif 317 318# Do we have a C++ compiler instead of a C compiler? 319GPP := $(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | grep g++) 320CLANGPP := $(shell echo $(CROSS_COMPILE)$(CC) | grep clang++) 321 322# g++ case 323ifneq ($(GPP),) 324CFLAGS := $(patsubst -std=c99, -std=c++2a, $(CFLAGS)) 325CFLAGS += -Wno-deprecated 326# Remove C++ unused pedantic flags 327CFLAGS := $(patsubst -Wstrict-prototypes,,$(CFLAGS)) 328CFLAGS := $(patsubst -Wjump-misses-init,,$(CFLAGS)) 329CFLAGS := $(patsubst -Wduplicated-branches,,$(CFLAGS)) 330CFLAGS := $(patsubst -Wno-declaration-after-statement,,$(CFLAGS)) 331endif 332# clang++ case 333ifneq ($(CLANGPP),) 334CFLAGS := $(patsubst -std=c99, -std=c++2a, $(CFLAGS)) 335CFLAGS += -Wno-deprecated -Wno-c++98-c++11-c++14-c++17-compat-pedantic -Wno-old-style-cast -Wno-zero-as-null-pointer-constant -Wno-c++98-compat-pedantic 336endif 337 338# Makefile verbosity 339ifeq ($(VERBOSE),1) 340VERBOSE_MAKE= 341else 342VERBOSE_MAKE=@ 343endif 344 345# Self tests parallelization 346ifeq ($(OPENMP_SELF_TESTS),1) 347CFLAGS += -DWITH_OPENMP_SELF_TESTS -fopenmp 348LDFLAGS += -fopenmp 349endif 350