From 9af60b6aa4df035a9627277f20f976019dfc8d8f Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 3 Oct 2019 17:39:35 +0200 Subject: embeddable-dll-service: add key generation function to replace bcrypt BCrypt is Win10+ and kind of clunky to use. The tunnel.dll binary has this code in it anyway, so doing it there doesn't actually increase the size of the binary. Signed-off-by: Jason A. Donenfeld --- embeddable-dll-service/csharp/Keypair.cs | 46 ++++----------------- embeddable-dll-service/csharp/Win32.cs | 70 -------------------------------- embeddable-dll-service/main.go | 20 +++++++++ 3 files changed, 27 insertions(+), 109 deletions(-) diff --git a/embeddable-dll-service/csharp/Keypair.cs b/embeddable-dll-service/csharp/Keypair.cs index 98a00a30..e5764fbd 100644 --- a/embeddable-dll-service/csharp/Keypair.cs +++ b/embeddable-dll-service/csharp/Keypair.cs @@ -4,7 +4,6 @@ */ using System; -using System.ComponentModel; using System.Runtime.InteropServices; namespace Tunnel @@ -20,46 +19,15 @@ namespace Tunnel Private = priv; } + [DllImport("tunnel.dll", EntryPoint = "WireGuardGenerateKeypair", CallingConvention = CallingConvention.Cdecl)] + private static extern bool WireGuardGenerateKeypair(byte[] publicKey, byte[] privateKey); + public static Keypair Generate() { - var algoHandle = new IntPtr(); - var statusCode = Win32.BCryptOpenAlgorithmProvider(ref algoHandle, Win32.BCRYPT_ECDH_ALGORITHM, null, 0); - if (statusCode > 0) - throw new Win32Exception((int)statusCode); - - try - { - var curveType = Win32.BCRYPT_ECC_CURVE_25519 + Char.MinValue; - statusCode = Win32.BCryptSetProperty(algoHandle, Win32.BCRYPT_ECC_CURVE_NAME, curveType, curveType.Length * sizeof(char), 0); - if (statusCode > 0) - throw new Win32Exception((int)statusCode); - var key = new IntPtr(); - statusCode = Win32.BCryptGenerateKeyPair(algoHandle, ref key, 255, 0); - if (statusCode > 0) - throw new Win32Exception((int)statusCode); - try - { - statusCode = Win32.BCryptFinalizeKeyPair(key, 0); - if (statusCode > 0) - throw new Win32Exception((int)statusCode); - - var keyBlob = new Win32.KeyBlob(); - int exportedKeySize = 0; - statusCode = Win32.BCryptExportKey(key, IntPtr.Zero, Win32.BCRYPT_ECCPRIVATE_BLOB, keyBlob, Marshal.SizeOf(typeof(Win32.KeyBlob)), out exportedKeySize); - if (statusCode > 0) - throw new Win32Exception((int)statusCode); - - return new Keypair(Convert.ToBase64String(keyBlob.Public), Convert.ToBase64String(keyBlob.Private)); - } - finally - { - Win32.BCryptDestroyKey(key); - } - } - finally - { - Win32.BCryptCloseAlgorithmProvider(algoHandle, 0); - } + var publicKey = new byte[32]; + var privateKey = new byte[32]; + WireGuardGenerateKeypair(publicKey, privateKey); + return new Keypair(Convert.ToBase64String(publicKey), Convert.ToBase64String(privateKey)); } } } diff --git a/embeddable-dll-service/csharp/Win32.cs b/embeddable-dll-service/csharp/Win32.cs index 3dd9cfca..76395f7e 100644 --- a/embeddable-dll-service/csharp/Win32.cs +++ b/embeddable-dll-service/csharp/Win32.cs @@ -171,75 +171,5 @@ namespace Tunnel [DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ChangeServiceConfig2(IntPtr hService, ServiceConfigType dwInfoLevel, ref ServiceDescription lpInfo); - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public class KeyBlob - { - BCRYPT_ECCKEY_BLOB Header; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] Public; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] Unused; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] Private; - } - - public const string BCRYPT_ECC_CURVE_NAME = "ECCCurveName"; - public const string BCRYPT_ECDH_ALGORITHM = "ECDH"; - public const string BCRYPT_ECC_CURVE_25519 = "curve25519"; - public const string BCRYPT_ECCPRIVATE_BLOB = "ECCPRIVATEBLOB"; - - [DllImport("bcrypt.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)] - public static extern uint BCryptSetProperty(IntPtr hObject, string property, string input, int inputSize, uint Flags = 0); - - [DllImport("bcrypt.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern uint BCryptOpenAlgorithmProvider(ref IntPtr hAlgorithm, string AlgId, string Implementation, uint Flags); - - [DllImport("bcrypt.dll", SetLastError = true)] - public static extern uint BCryptGenerateKeyPair(IntPtr hObject, ref IntPtr hKey, uint length, uint Flags); - - [DllImport("bcrypt.dll", SetLastError = true)] - public static extern uint BCryptFinalizeKeyPair(IntPtr hKey, uint Flags); - - [DllImport("bcrypt.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)] - public static extern uint BCryptExportKey(IntPtr hKey, IntPtr hExportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Out] KeyBlob pbOutput, int cbOutput, out int pcbResult, uint Flags = 0); - - [DllImport("bcrypt.dll", SetLastError = true)] - public static extern uint BCryptDestroyKey(IntPtr hKey); - - [DllImport("bcrypt.dll", SetLastError = true)] - public static extern uint BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, uint Flags); - - [DllImport("bcrypt.dll", SetLastError = true)] - public static extern uint BCryptDestroySecret(IntPtr hSecretAgreement); - - [DllImport("bcrypt.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern uint BCryptImportKeyPair(IntPtr hAlgorithm, IntPtr hImportKey, string BlobType, ref IntPtr hPublicKey, byte[] Input, uint InputByteLength, uint Flags); - - [DllImport("bcrypt.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern uint BCryptSecretAgreement(IntPtr hPrivKey, IntPtr hPublicKey, ref IntPtr phSecret, uint Flags); - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public class BCryptBufferDesc - { - public uint ulVersion; - public uint cBuffers; - public IntPtr pBuffers; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public class BCryptBuffer - { - public uint cbBuffer; - public uint bufferType; - public IntPtr pvBuffer; - } - - [StructLayout(LayoutKind.Sequential)] - public class BCRYPT_ECCKEY_BLOB - { - uint magic; - uint cbKey; - } } } diff --git a/embeddable-dll-service/main.go b/embeddable-dll-service/main.go index a8ce7c10..edf72fba 100644 --- a/embeddable-dll-service/main.go +++ b/embeddable-dll-service/main.go @@ -7,10 +7,16 @@ package main import ( "C" + + "golang.org/x/crypto/curve25519" + "golang.zx2c4.com/wireguard/windows/conf" "golang.zx2c4.com/wireguard/windows/tunnel" + + "crypto/rand" "log" "path/filepath" + "unsafe" ) //export WireGuardTunnelService @@ -24,4 +30,18 @@ func WireGuardTunnelService(confFile string) bool { return err == nil } +//export WireGuardGenerateKeypair +func WireGuardGenerateKeypair(publicKey *byte, privateKey *byte) { + publicKeyArray := (*[32]byte)(unsafe.Pointer(publicKey)) + privateKeyArray := (*[32]byte)(unsafe.Pointer(privateKey)) + n, err := rand.Read(privateKeyArray[:]) + if err != nil || n != len(privateKeyArray) { + panic("Unable to generate random bytes") + } + privateKeyArray[0] &= 248 + privateKeyArray[31] = (privateKeyArray[31] & 127) | 64 + + curve25519.ScalarBaseMult(publicKeyArray, privateKeyArray) +} + func main() {} -- cgit v1.2.3-59-g8ed1b