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
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to