Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Arm64 Support for Windows #1837

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions osdep/WindowsEthernetTap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ class WindowsEthernetTapEnv
{
#ifdef _WIN64
is64Bit = TRUE;
#ifdef _M_ARM64
tapDriverPath = "\\tap-windows\\arm64\\zttap300.inf";
#else
tapDriverPath = "\\tap-windows\\x64\\zttap300.inf";
#endif

#else
is64Bit = FALSE;
IsWow64Process(GetCurrentProcess(),&is64Bit);
Expand Down
5 changes: 3 additions & 2 deletions windows/TapDriver6/tap.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
#define __TAP_H

#ifndef NDIS_SUPPORT_NDIS6
#define NDIS_MINIPORT_DRIVER 1
#define NDIS_SUPPORT_NDIS6 1
#define NDIS_SUPPORT_NDIS61 1
#define NDIS_SUPPORT_NDIS630 1
#define NDIS_WDM1 1
#define NDIS61_MINIPORT 1
#define NDIS630_MINIPORT 1
#endif

#include <ntifs.h>
Expand Down
7 changes: 6 additions & 1 deletion windows/TapDriver6/zttap300.inf
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ DeviceDescription = "ZeroTier Virtual Port"
Provider = "ZeroTier"

[Manufacturer]
%Provider%=zttap300,NTx86
;%Provider%=zttap300,NTx86
;%Provider%=zttap300,NTamd64
%Provider%=zttap300,NTarm64

[zttap300.NTx86]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
Expand All @@ -45,6 +46,10 @@ Provider = "ZeroTier"
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy

[zttap300.NTarm64]
%DeviceDescription% = zttap300.ndi, root\zttap300 ; Root enumerated
%DeviceDescription% = zttap300.ndi, zttap300 ; Legacy

;----------------- Characteristics ------------
; NCF_PHYSICAL = 0x04
; NCF_VIRTUAL = 0x01
Expand Down
2 changes: 1 addition & 1 deletion windows/ZeroTierOne/ZeroTierOne.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>wbemuuid.lib;wsock32.lib;ws2_32.lib;Iphlpapi.lib;Rpcrt4.lib;zeroidc.lib;bcrypt.lib;userenv.lib;crypt32.lib;secur32.lib;ncrypt.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>$(SolutionDir)..\zeroidc\target\x86_64-pc-windows-msvc\release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(SolutionDir)..\zeroidc\target\aarch64-pc-windows-msvc\release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
Expand Down
2 changes: 0 additions & 2 deletions zeroidc/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions zeroidc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ thiserror = "1"

[build-dependencies]
cbindgen = "0.20"

[patch.crates-io]
ring = { path = "vendor/ring" }
2 changes: 1 addition & 1 deletion zeroidc/vendor/ring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ wasm32_c = []
version = "0.3.37"
features = ["Crypto", "Window"]
default-features = false
[target."cfg(any(target_arch = \"x86\",target_arch = \"x86_64\", all(any(target_arch = \"aarch64\", target_arch = \"arm\"), any(target_os = \"android\", target_os = \"fuchsia\", target_os = \"linux\"))))".dependencies.spin]
[target."cfg(any(target_arch = \"x86\",target_arch = \"x86_64\", all(any(target_arch = \"aarch64\", target_arch = \"arm\"), any(target_os = \"android\", target_os = \"fuchsia\", target_os = \"linux\", target_os = \"windows\"))))".dependencies.spin]
version = "0.5.2"
default-features = false
[target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dependencies.libc]
Expand Down
13 changes: 7 additions & 6 deletions zeroidc/vendor/ring/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ const ASM_TARGETS: &[(&str, Option<&str>, Option<&str>)] = &[
("aarch64", Some("ios"), Some("ios64")),
("aarch64", Some("macos"), Some("ios64")),
("aarch64", None, Some("linux64")),
("aarch64", Some(WINDOWS), Some("win64")),
("x86", Some(WINDOWS), Some("win32n")),
("x86", Some("ios"), Some("macosx")),
("x86", None, Some("elf")),
Expand Down Expand Up @@ -384,7 +385,7 @@ fn build_c_code(target: &Target, pregenerated: PathBuf, out_dir: &Path) {
// For Windows we also pregenerate the object files for non-Git builds so
// the user doesn't need to install the assembler. On other platforms we
// assume the C compiler also assembles.
if use_pregenerated && target.os == WINDOWS {
if use_pregenerated && (target.os == WINDOWS && target.arch != "aarch64") {
// The pregenerated object files always use ".obj" as the extension,
// even when the C/C++ compiler outputs files with the ".o" extension.
asm_srcs = asm_srcs
Expand Down Expand Up @@ -503,7 +504,7 @@ fn compile(
let mut out_path = out_dir.join(p.file_name().unwrap());
assert!(out_path.set_extension(target.obj_ext));
if need_run(&p, &out_path, includes_modified) {
let cmd = if target.os != WINDOWS || ext != "asm" {
let cmd = if !(target.os == WINDOWS && target.arch != "aarch64") || ext != "asm" {
cc(p, ext, target, warnings_are_errors, &out_path)
} else {
nasm(p, &target.arch, &out_path)
Expand Down Expand Up @@ -675,7 +676,7 @@ fn perlasm_src_dsts(
let mut src_dsts = srcs
.iter()
.filter(|p| is_perlasm(p))
.map(|src| (src.clone(), asm_path(out_dir, src, os, perlasm_format)))
.map(|src| (src.clone(), asm_path(out_dir, src, arch, os, perlasm_format)))
.collect::<Vec<_>>();

// Some PerlAsm source files need to be run multiple times with different
Expand All @@ -688,7 +689,7 @@ fn perlasm_src_dsts(
let synthesized_path = PathBuf::from(synthesized);
src_dsts.push((
concrete_path,
asm_path(out_dir, &synthesized_path, os, perlasm_format),
asm_path(out_dir, &synthesized_path, arch, os, perlasm_format),
))
}
};
Expand All @@ -710,11 +711,11 @@ fn is_perlasm(path: &PathBuf) -> bool {
path.extension().unwrap().to_str().unwrap() == "pl"
}

fn asm_path(out_dir: &Path, src: &Path, os: Option<&str>, perlasm_format: &str) -> PathBuf {
fn asm_path(out_dir: &Path, src: &Path, arch: &str, os: Option<&str>, perlasm_format: &str) -> PathBuf {
let src_stem = src.file_stem().expect("source file without basename");

let dst_stem = src_stem.to_str().unwrap();
let dst_extension = if os == Some("windows") { "asm" } else { "S" };
let dst_extension = if os == Some("windows") && arch != "aarch64" { "asm" } else { "S" };
let dst_filename = format!("{}-{}.{}", dst_stem, perlasm_format, dst_extension);
out_dir.join(dst_filename)
}
Expand Down
15 changes: 12 additions & 3 deletions zeroidc/vendor/ring/crypto/fipsmodule/bn/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@
#pragma intrinsic(_umul128)
#endif

#if defined(OPENSSL_AARCH64) && defined(_MSC_VER) && ! defined(__clang__)
#pragma warning(push, 3)
#include <intrin.h>
#pragma warning(pop)
#pragma intrinsic(_umul128)
#endif

#include "../../internal.h"

typedef crypto_word BN_ULONG;
Expand Down Expand Up @@ -187,10 +194,12 @@ static inline void bn_umult_lohi(BN_ULONG *low_out, BN_ULONG *high_out,
BN_ULONG a, BN_ULONG b) {
#if defined(OPENSSL_X86_64) && defined(_MSC_VER) && !defined(__clang__)
*low_out = _umul128(a, b, high_out);
#elif defined(OPENSSL_AARCH64) && defined(_MSC_VER) && ! defined(__clang__)
*low_out = _umul128(a, b, high_out);
#else
BN_ULLONG result = (BN_ULLONG)a * b;
*low_out = (BN_ULONG)result;
*high_out = (BN_ULONG)(result >> BN_BITS2);
BN_ULLONG result = (BN_ULLONG)a * b;
*low_out = (BN_ULONG)result;
*high_out = (BN_ULONG)(result >> BN_BITS2);
#endif
}

Expand Down
25 changes: 22 additions & 3 deletions zeroidc/vendor/ring/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) fn features() -> Features {
target_arch = "x86_64",
all(
any(target_arch = "aarch64", target_arch = "arm"),
any(target_os = "android", target_os = "fuchsia", target_os = "linux")
any(target_os = "android", target_os = "fuchsia", target_os = "linux", target_os = "windows")
)
))]
{
Expand All @@ -49,7 +49,7 @@ pub(crate) fn features() -> Features {

#[cfg(all(
any(target_arch = "aarch64", target_arch = "arm"),
any(target_os = "android", target_os = "fuchsia", target_os = "linux")
any(target_os = "android", target_os = "fuchsia", target_os = "linux", target_os = "windows")
))]
{
arm::setup();
Expand Down Expand Up @@ -162,6 +162,25 @@ pub(crate) mod arm {
}
}

#[cfg(all(target_os = "windows", target_arch = "aarch64"))]
pub fn setup() {
// We do not need to check for the presence of NEON, as Armv8-A always has it
let mut features = NEON.mask;

let result = unsafe {
winapi::um::processthreadsapi::IsProcessorFeaturePresent(
winapi::um::winnt::PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE,
)
};

if result != 0 {
// These are all covered by one call in Windows
features |= AES.mask;
features |= PMULL.mask;
features |= SHA256.mask;
}
}

macro_rules! features {
{
$(
Expand Down Expand Up @@ -237,7 +256,7 @@ pub(crate) mod arm {
}

#[cfg(all(
any(target_os = "android", target_os = "fuchsia", target_os = "linux"),
any(target_os = "android", target_os = "fuchsia", target_os = "linux", target_os = "windows"),
any(target_arch = "arm", target_arch = "aarch64")
))]
{
Expand Down