1

I'm working under the VS2013 ARM Developer Prompt. I'm trying to use Microsoft's Cryptography Next Generation (CNG), but I'm experiencing some non-trivial problems.

I'm trying to compile a simple test program:

#include <windows.h>
#include <bcrypt.h>

int main(int argc, char* argv[])
{
    BCRYPT_ALG_HANDLE hProvider = NULL;
    NTSTATUS ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -1;
    }

    unsigned char buffer[20];
    ret = BCryptGenRandom(hProvider, buffer, (ULONG)sizeof(buffer), 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -2;
    }

    ret = BCryptCloseAlgorithmProvider(hProvider, 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -3;
    }

    return 0;
}

I attempt to compile it with:

C:\Users\Test>cl.exe /nologo /W4 /D_MBCS /Zi /TP /EHs c /MD /FI sdkddkver.h /FI winapifamily.h /DWINAPI_FAMILY=WINAPI_FAMILY_APP /c test.cxx
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for ARM
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cxx
test.cxx(6) : error C2065: 'BCRYPT_ALG_HANDLE' : undeclared identifier
test.cxx(6) : error C2146: syntax error : missing ';' before identifier 'hProvid
er'
test.cxx(6) : error C2065: 'hProvider' : undeclared identifier
test.cxx(7) : error C2065: 'NTSTATUS' : undeclared identifier
test.cxx(7) : error C2146: syntax error : missing ';' before identifier 'ret'
test.cxx(7) : error C2065: 'ret' : undeclared identifier
test.cxx(7) : error C2065: 'hProvider' : undeclared identifier
test.cxx(7) : error C2065: 'BCRYPT_RNG_ALGORITHM' : undeclared identifier
test.cxx(7) : error C2065: 'MS_PRIMITIVE_PROVIDER' : undeclared identifier
test.cxx(7) : error C3861: 'BCryptOpenAlgorithmProvider': identifier not found
test.cxx(8) : error C2065: 'ret' : undeclared identifier
test.cxx(8) : error C3861: 'BCRYPT_SUCCESS': identifier not found
test.cxx(14) : error C2065: 'ret' : undeclared identifier
test.cxx(14) : error C2065: 'hProvider' : undeclared identifier
test.cxx(14) : error C3861: 'BCryptGenRandom': identifier not found
test.cxx(15) : error C2065: 'ret' : undeclared identifier
test.cxx(15) : error C3861: 'BCRYPT_SUCCESS': identifier not found
test.cxx(20) : error C2065: 'ret' : undeclared identifier
test.cxx(20) : error C2065: 'hProvider' : undeclared identifier
test.cxx(20) : error C3861: 'BCryptCloseAlgorithmProvider': identifier not found

test.cxx(21) : error C2065: 'ret' : undeclared identifier
test.cxx(21) : error C3861: 'BCRYPT_SUCCESS': identifier not found

When I attempt to include <ntstatus.h> (scrapped from PJ Naughter's blog because I can't seem to find anything useful from Microsoft):

cl.exe /nologo /W4 /D_MBCS /Zi /TP /EHsc /MD /FI sdkddkver.h /FI winapifamily.h /DWINAPI_FAMILY=WINAPI_FAMILY_APP /c osrng.cpp
osrng.cpp
C:\Program Files (x86)\Windows Kits\8.1\include\shared\ntstatus.h(66) : warning
C4005: 'STATUS_WAIT_0' : macro redefinition
        C:\Program Files (x86)\Windows Kits\8.1\include\um\winnt.h(2202) : see p
revious definition of 'STATUS_WAIT_0'
C:\Program Files (x86)\Windows Kits\8.1\include\shared\ntstatus.h(212) : warning
 C4005: 'STATUS_ABANDONED_WAIT_0' : macro redefinition
        C:\Program Files (x86)\Windows Kits\8.1\include\um\winnt.h(2203) : see p
revious definition of 'STATUS_ABANDONED_WAIT_0'
C:\Program Files (x86)\Windows Kits\8.1\include\shared\ntstatus.h(235) : warning
 C4005: 'STATUS_USER_APC' : macro redefinition
...

I can't make it a LONG because Microsoft macros like BCRYPT_SUCCESS cast it to a NTSTATUS code.

I can also duplicate the missing NTSTATUS problem under VS2012 ARM Developer Prompt.

What header file should I include to get a declaration for NTSTATUS under ARM?


I think this might be related, but I'm not certain: fatal error LNK1104: cannot open file 'bcrypt.lib' when building for Surface RT tablet. About all I know is this stuff does not appear to be well tested by Microsoft because there are too many damn problems trying to use it.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885

1 Answers1

4

The main issue is that BCRYPT is supported for the Universal Windows Platform apps (aka Windows 10 Store apps), but was not supported for Windows 8.x Store apps. VS 2013 toolset always uses the Windows 8.1 SDK so you were building a Windows 8.1 Store app. When you tried VS 2012, you were using the Windows 8.0 SDK so you were building a Windows 8.0 Store apps. Again, neither of this support BCRYPT. If you build with VS 2015 and have the Windows 10 SDK installed, then your code builds fine.

Note that /D_MBCS is not an option for Windows Store apps. All Windows Store apps should be built for Unicode /DUNICODE /D_UNICODE and not ANSI/Multibyte as you were trying to do.

Also, be sure to link with windowsapp.lib to make sure you pick up the correct DLLs when you link.

You can easily confirm that all the errors you are seeing happen in VS 2012/2013 if you do not have #include <bcrypt.h> in the file at all. The DWINAPI_FAMILY=WINAPI_FAMILY_APP ensures that all unsupported APIs are undefined, so with Windows 8.x Store that header was basically an empty file.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Thanks Chuck. It appears all of Microsoft's documents are broken. See, for example, [`BCryptOpenAlgorithmProvider`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa375479%28v=vs.85%29.aspx), [`BCryptGenRandom`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa375458%28v=vs.85%29.aspx) and [`BCryptCloseAlgorithmProvider`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375377%28v=vs.85%29.aspx). – jww May 01 '16 at 06:21
  • They are all say "Windows Store apps" because these APIs are supported for Windows 10. I agree it's not helpful to you that it fails to mention "UWP" or "Windows 10", but at this point MSDN is only telling you about UWP not Windows 8.x Store. – Chuck Walbourn May 01 '16 at 06:23
  • Thanks again Chuck. Would you mind taking a look at [Preprocessor definitions for Universal Windows Platform?](http://stackoverflow.com/q/36072350). These questions are holding up the port of a few C/C++ libraries I work with (OpenSSL, Crypto++, Cryptlib and Botan). – jww May 01 '16 at 21:13
  • Thanks again Chuck. Why does Microsoft state the API is available in [NIST documents](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1893.pdf)? The documents on file with NIST are legally binding (unlike broken MSDN documentation). Here are the platforms they claim to provide the API: Microsoft Windows 8, Microsoft Windows Server 2012, Microsoft Windows RT, Microsoft Surface Windows RT, Microsoft Surface Windows 8 Pro, Microsoft Windows Phone 8, Microsoft Windows Storage Server 2012. – jww May 01 '16 at 22:42
  • All those platforms support the BCrypt APIs, but they aren't available to Windows Store apps (aka Metro style apps) in Windows 8.x directly. Instead you can use the Windows Runtime class [HashAlgorithmProvider](https://msdn.microsoft.com/en-us/library/windows.security.cryptography.core.hashalgorithmprovider.aspx). There is also a limited form of Win32 development for ARM devices for OEMs. That said, I'm not an expert in government compliance so you should contact Microsoft directly. For the Universal Windows Platform, the original Win32 BCrypt APIs are exposed to UWP apps. – Chuck Walbourn May 02 '16 at 02:55
  • *". If you build with VS 2015 and have the Windows 10 SDK installed, then your code builds fine."* - We're testing Botan under VS2015 with Windows 10 Kit installed, but same problem. Damn I wish Microsoft would test their shit and stop dumping it on unsuspecting developers. – jww Sep 12 '17 at 18:10
  • Are you building a UWP, a Win32 desktop app, or a Windows Store 8.x app? Are you using the Windows 8.1 SDK or a Windows 10 SDK? – Chuck Walbourn Sep 12 '17 at 18:13
  • See [Pull Request 1180, Refactoring to support Windows Phone](https://github.com/randombit/botan/pull/1180). I've been trying to get this stuff to work for years. I bought the Visual Studio's, the ARM tablets, the ARM phones, etc. I've spent thousands of dollars on test gear and ***it has never worked***. And forget documentation like Nmake or MSBuild from the command line. Microsoft simply won't provide it. – jww Sep 12 '17 at 18:30