1 /* ==================================================================== 2 * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * openssl-core@openssl.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This product includes cryptographic software written by Eric Young 50 * (eay@cryptsoft.com). This product includes software written by Tim 51 * Hudson (tjh@cryptsoft.com). */ 52 53 #ifndef OPENSSL_HEADER_ARM_ARCH_H 54 #define OPENSSL_HEADER_ARM_ARCH_H 55 56 // arm_arch.h contains symbols used by ARM assembly, and the C code that calls 57 // it. It is included as a public header to simplify the build, but is not 58 // intended for external use. 59 60 #if defined(__ARMEL__) || defined(_M_ARM) || defined(__AARCH64EL__) || \ 61 defined(_M_ARM64) 62 63 // ARMV7_NEON is true when a NEON unit is present in the current CPU. 64 #define ARMV7_NEON (1 << 0) 65 66 // ARMV8_AES indicates support for hardware AES instructions. 67 #define ARMV8_AES (1 << 2) 68 69 // ARMV8_SHA1 indicates support for hardware SHA-1 instructions. 70 #define ARMV8_SHA1 (1 << 3) 71 72 // ARMV8_SHA256 indicates support for hardware SHA-256 instructions. 73 #define ARMV8_SHA256 (1 << 4) 74 75 // ARMV8_PMULL indicates support for carryless multiplication. 76 #define ARMV8_PMULL (1 << 5) 77 78 // ARMV8_SHA512 indicates support for hardware SHA-512 instructions. 79 #define ARMV8_SHA512 (1 << 6) 80 81 #if defined(__ASSEMBLER__) 82 83 // We require the ARM assembler provide |__ARM_ARCH| from Arm C Language 84 // Extensions (ACLE). This is supported in GCC 4.8+ and Clang 3.2+. MSVC does 85 // not implement ACLE, but we require Clang's assembler on Windows. 86 #if !defined(__ARM_ARCH) 87 #error "ARM assembler must define __ARM_ARCH" 88 #endif 89 90 // __ARM_ARCH__ is used by OpenSSL assembly to determine the minimum target ARM 91 // version. 92 // 93 // TODO(davidben): Switch the assembly to use |__ARM_ARCH| directly. 94 #define __ARM_ARCH__ __ARM_ARCH 95 96 // Even when building for 32-bit ARM, support for aarch64 crypto instructions 97 // will be included. 98 #define __ARM_MAX_ARCH__ 8 99 100 // Support macros for 101 // - Armv8.3-A Pointer Authentication and 102 // - Armv8.5-A Branch Target Identification 103 // features which require emitting a .note.gnu.property section with the 104 // appropriate architecture-dependent feature bits set. 105 // 106 // |AARCH64_SIGN_LINK_REGISTER| and |AARCH64_VALIDATE_LINK_REGISTER| expand to 107 // PACIxSP and AUTIxSP, respectively. |AARCH64_SIGN_LINK_REGISTER| should be 108 // used immediately before saving the LR register (x30) to the stack. 109 // |AARCH64_VALIDATE_LINK_REGISTER| should be used immediately after restoring 110 // it. Note |AARCH64_SIGN_LINK_REGISTER|'s modifications to LR must be undone 111 // with |AARCH64_VALIDATE_LINK_REGISTER| before RET. The SP register must also 112 // have the same value at the two points. For example: 113 // 114 // .global f 115 // f: 116 // AARCH64_SIGN_LINK_REGISTER 117 // stp x29, x30, [sp, #-96]! 118 // mov x29, sp 119 // ... 120 // ldp x29, x30, [sp], #96 121 // AARCH64_VALIDATE_LINK_REGISTER 122 // ret 123 // 124 // |AARCH64_VALID_CALL_TARGET| expands to BTI 'c'. Either it, or 125 // |AARCH64_SIGN_LINK_REGISTER|, must be used at every point that may be an 126 // indirect call target. In particular, all symbols exported from a file must 127 // begin with one of these macros. For example, a leaf function that does not 128 // save LR can instead use |AARCH64_VALID_CALL_TARGET|: 129 // 130 // .globl return_zero 131 // return_zero: 132 // AARCH64_VALID_CALL_TARGET 133 // mov x0, #0 134 // ret 135 // 136 // A non-leaf function which does not immediately save LR may need both macros 137 // because |AARCH64_SIGN_LINK_REGISTER| appears late. For example, the function 138 // may jump to an alternate implementation before setting up the stack: 139 // 140 // .globl with_early_jump 141 // with_early_jump: 142 // AARCH64_VALID_CALL_TARGET 143 // cmp x0, #128 144 // b.lt .Lwith_early_jump_128 145 // AARCH64_SIGN_LINK_REGISTER 146 // stp x29, x30, [sp, #-96]! 147 // mov x29, sp 148 // ... 149 // ldp x29, x30, [sp], #96 150 // AARCH64_VALIDATE_LINK_REGISTER 151 // ret 152 // 153 // .Lwith_early_jump_128: 154 // ... 155 // ret 156 // 157 // These annotations are only required with indirect calls. Private symbols that 158 // are only the target of direct calls do not require annotations. Also note 159 // that |AARCH64_VALID_CALL_TARGET| is only valid for indirect calls (BLR), not 160 // indirect jumps (BR). Indirect jumps in assembly are currently not supported 161 // and would require a macro for BTI 'j'. 162 // 163 // Although not necessary, it is safe to use these macros in 32-bit ARM 164 // assembly. This may be used to simplify dual 32-bit and 64-bit files. 165 // 166 // References: 167 // - "ELF for the Arm® 64-bit Architecture" 168 // https://github.com/ARM-software/abi-aa/blob/master/aaelf64/aaelf64.rst 169 // - "Providing protection for complex software" 170 // https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software 171 172 #if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 173 #define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has Branch Target Identification 174 #define AARCH64_VALID_CALL_TARGET hint #34 // BTI 'c' 175 #else 176 #define GNU_PROPERTY_AARCH64_BTI 0 // No Branch Target Identification 177 #define AARCH64_VALID_CALL_TARGET 178 #endif 179 180 #if defined(__ARM_FEATURE_PAC_DEFAULT) && \ 181 (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 // Signed with A-key 182 #define GNU_PROPERTY_AARCH64_POINTER_AUTH \ 183 (1 << 1) // Has Pointer Authentication 184 #define AARCH64_SIGN_LINK_REGISTER hint #25 // PACIASP 185 #define AARCH64_VALIDATE_LINK_REGISTER hint #29 // AUTIASP 186 #elif defined(__ARM_FEATURE_PAC_DEFAULT) && \ 187 (__ARM_FEATURE_PAC_DEFAULT & 2) == 2 // Signed with B-key 188 #define GNU_PROPERTY_AARCH64_POINTER_AUTH \ 189 (1 << 1) // Has Pointer Authentication 190 #define AARCH64_SIGN_LINK_REGISTER hint #27 // PACIBSP 191 #define AARCH64_VALIDATE_LINK_REGISTER hint #31 // AUTIBSP 192 #else 193 #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 // No Pointer Authentication 194 #if GNU_PROPERTY_AARCH64_BTI != 0 195 #define AARCH64_SIGN_LINK_REGISTER AARCH64_VALID_CALL_TARGET 196 #else 197 #define AARCH64_SIGN_LINK_REGISTER 198 #endif 199 #define AARCH64_VALIDATE_LINK_REGISTER 200 #endif 201 202 #if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0 203 .pushsection .note.gnu.property, "a"; 204 .balign 8; 205 .long 4; 206 .long 0x10; 207 .long 0x5; 208 .asciz "GNU"; 209 .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ 210 .long 4; 211 .long (GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI); 212 .long 0; 213 .popsection; 214 #endif 215 216 #endif // __ASSEMBLER__ 217 218 #endif // __ARMEL__ || _M_ARM || __AARCH64EL__ || _M_ARM64 219 220 #endif // OPENSSL_HEADER_ARM_ARCH_H 221