Hi,
As a few of you have heard on IRC, I'm a Microsoft engineer working on the
ARM64 version of Windows desktop, mostly on the x86 usermode emulation layers.
One of the challenges usermode-only emulation poses is that applications
relying on drivers don't run unless the driver is ported. There has been quite
some interest in OpenVPN on my team and my proof of concept went well, so I am
taking a shot at porting tap-windows6 to ARM64 and contributing the port back
to the community.
(I'll have patches to share soon! Please bear with me.)
My proof of concept was pretty simple: Copy the source files into a VS2017
driver project, tweak the project properties to reflect the SOURCES file, lie
about the NDIS version, and suddenly I had a working ARM64 tap0901.sys through
which I could ping an OpenVPN server's VPN-side IP. Not bad!
Needless to say, a lot more work is required to ship this. I've already done a
lot of it, and I'm planning to do the rest--but I'd love help, even if just
advice and historical perspective.
The work splits into a few different buckets; I'm interested in your thoughts
about my approach:
The Windows Driver Kit only supports ARM64 drivers from Windows 10 1709
forward, so tap-windows6's build system needed to migrate to the newer SDK,
complete with new folder names and build engine semantics. Just switching SDKs
required no driver code changes and I expect it should still run downlevel to
Win7, if not Vista (but I haven't yet tested anything but Win10!). BuildTap.py
needed a moderate number of straightforward changes.
Appveyor will need to be updated to handle the environment and output changes;
I'm happy to explain what's needed, but I have no previous experience with the
service.
Along with the SDK changes, the build script needed many changes to add a third
architecture (ARM64).
The installer also needed changes to support ARM64. I've written an NSIS header
to replace x64.nsh to make this easy. (Complex NSIS scripting...um...ouch.
Just...ouch. :)
The driver does technically need code changes, though: ARM64 Windows only
supports NDIS >=6.30, while Windows 7 only supports NDIS <= 6.20. If I find
that these changes are small enough, I'll simply base them on the NDIS version
supported by the OS. If they're bigger, supporting two (or many) NDIS versions
gets messy. I'm just starting on this now, but the NDIS maintainers made it
sound somewhat simple for a driver that doesn't interact with hardware.
I cracked open the devcon.exe sample from the Win7 DDK and the only change I
had to make was renaming the binary to tapinstall.exe. For the new build
system, I pulled the latest devcon sources from
https://github.com/Microsoft/Windows-driver-samples/tree/master/setup/devcon
and built it with the new WDK, then renamed it to tapinstall.exe in
buildtap.py. This might break the current signing pattern. I did make one
change to support ARM64 as a build target, and it's under review:
https://github.com/Microsoft/Windows-driver-samples/pull/238
As for whether or not the Microsoft code can now be redistributed, I think the
'clone the Microsoft repo' is a fairly easy way forward. On the other hand, the
MS-PL isn't nearly as heavy as anything that the DDK came with:
https://raw.githubusercontent.com/Microsoft/Windows-driver-samples/master/LICENSE
As for signing, I get similar errors before and after my changes. I'm not quite
sure what the goal is for which script section, but it does appear that the new
build system invokes Inf2Cat itself using the test certs provided with the SDK.
Since that doesn't cover tapinstall.exe or the installer EXE nor does it cover
the official attestation case, it's insufficient. (I'll keep my ear to the
ground about making this signing stuff more palatable in general.)
The x86 usermode daemon and UI work beautifully with the ARM64 driver, so
bundling the properly-tri-arch tap-windows6 installer with the x86 usermode
should be fine for now for the user experience. As pointed out on IRC, this is
a big potential bottleneck since this is where the cryptography and routing are
done, but it just works for now and I don't have the resources to add the ARM64
Windows ABI to GCC+mingw nor do I feel a pressing need to resuscitate the old
MSVC openvpn-build paths and then hope the community is happy supporting that
in the future, seeing as how it's currently unsupported.
Going forward I'll be happy to smoke-test new versions of OpenVPN on an ARM64
device, as long as I have one available.
Overall, I think ARM64 support only requires changes to tap-windows6 and the
build environment, but there are a lot of little changes. I'd love to hear your
feedback, and I'm sure I missed explaining something.
Thanks,
Jon Kunkee
(Shout out to kitsune1, cron2, mattock, pekster, and others who have given me
feedback on IRC to get me this far!)
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel