1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc.
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies.
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/crypto.h>
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h"
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if !defined(OPENSSL_NO_ASM) && \
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley     defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* x86, x86_64 and the ARMs need to record the result of a cpuid call for the
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * asm to work correctly, unless compiled without asm code. */
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define NEED_CPUID
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Otherwise, don't emit a static initialiser. */
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define BORINGSSL_NO_STATIC_INITIALIZER
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif  /* !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64 ||
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                               OPENSSL_ARM || OPENSSL_AARCH64) */
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* The capability variables are defined in this file in order to work around a
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * linker bug. When linking with a .a, if no symbols in a .o are referenced
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * then the .o is discarded, even if it has constructor functions.
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This still means that any binaries that don't include some functionality
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * that tests the capability values will still skip the constructor but, so
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * far, the init constructor function only sets the capability variables. */
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This value must be explicitly initialised to zero in order to work around a
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * bug in libtool or the linker on OS X.
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If not initialised then it becomes a "common symbol". When put into an
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * archive, linking on OS X will fail to resolve common symbols. By
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * initialising it to zero, it becomes a "data symbol", which isn't so
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * affected. */
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyuint32_t OPENSSL_ia32cap_P[4] = {0};
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "arm_arch.h"
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(__ARM_NEON__)
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyuint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyuint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(OPENSSL_WINDOWS)
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define OPENSSL_CDECL __cdecl
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define OPENSSL_CDECL
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if !defined(OPENSSL_WINDOWS)
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void do_library_init(void) __attribute__ ((constructor));
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#pragma section(".CRT$XCU", read)
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void __cdecl do_library_init(void);
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    do_library_init;
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif  /* !BORINGSSL_NO_STATIC_INITIALIZER */
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* do_library_init is the actual initialization function. If
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * initializer. Otherwise, it is called by CRYPTO_library_init. */
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void OPENSSL_CDECL do_library_init(void) {
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* WARNING: this function may only configure the capability variables. See the
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  * note above about the linker bug. */
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(NEED_CPUID)
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_cpuid_setup();
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid CRYPTO_library_init(void) {
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* TODO(davidben): It would be tidier if this build knob could be replaced
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * with an internal lazy-init mechanism that would handle things correctly
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * in-library. */
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  do_library_init();
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
105f40f42df67fffec64967b000e4fdad4b435611a5Adam Langley
106f40f42df67fffec64967b000e4fdad4b435611a5Adam Langleyconst char *SSLeay_version(int unused) {
10758dc65d0b61c75c2d7ffcc942ec4e9f43b70b9ccAdam Langley  return "BoringSSL";
108f40f42df67fffec64967b000e4fdad4b435611a5Adam Langley}
109f40f42df67fffec64967b000e4fdad4b435611a5Adam Langley
11058dc65d0b61c75c2d7ffcc942ec4e9f43b70b9ccAdam Langleyunsigned long SSLeay(void) {
11158dc65d0b61c75c2d7ffcc942ec4e9f43b70b9ccAdam Langley  return OPENSSL_VERSION_NUMBER;
112f40f42df67fffec64967b000e4fdad4b435611a5Adam Langley}
113