1

In Visual Studio 2012, I'm trying to encrypt a file with Crypto++ library with AES encryption and CBC mode as following :

#include <Windows.h>
#include "aes.h"
#include "modes.h"
#include "files.h"
#include <Shlwapi.h>

using namespace CryptoPP;

INT main(INT argc, CHAR *argv[])
{
    CHAR szKey[16] = {0};
    CHAR szInitVector[AES::DEFAULT_KEYLENGTH] = {0};

    StrCpyA(szKey, "qqwweeff88lliioo");
    StrCpyA(szInitVector, "eerrttooppkkllhh");

    CBC_Mode<AES>::Encryption encryptor((byte*)szKey, AES::DEFAULT_KEYLENGTH, (byte*)szInitVector);
    FileSource fs("in.txt", true, new StreamTransformationFilter(encryptor, new FileSink("out.aes")));

    return 0;
}

In Qt it does work!, But here I wondered why got the following error :

error C2872: 'byte' : ambiguous symbol
could be 'c:\program files (x86)\windows kits\8.0\include\shared\rpcndr.h(164) : unsigned char byte'
or 'z:\cryptography\app_aesencryption\aes headers\config.h(237) : CryptoPP::byte'

Due to prevent of ambiguous symbol error, even I cast bellow statement with CryptoPP::byte* :

CBC_Mode<AES>::Encryption encryptor((CryptoPP::byte*)szKey, AES::DEFAULT_KEYLENGTH, (CryptoPP::byte*)szInitVector);

I didn't get any error for 'byte' : ambiguous symbol, But It give me many errors as :

error LNK 2038

By the way, I linked .lib file of Crypto++, So I think this error is Unlikely for this. Is last error related to CryptoPP::byte*? Is there any solution?

4 Answers4

2

'byte' : ambiguous symbol error when using of Crypto++

We had to move byte from global namespace to CryptoPP namespace due to C++17 and std::byte. The change occurred at Commit 00f9818b5d8e, which was part of the Crypto++ 6.0 release.

Crypto++ used to put byte in the global namespace for compatibility with Microsoft SDKs. Without the global byte then you would encounter 'byte' : ambiguous symbol error again.

The error you are seeing is because you used using namespace CryptoPP; and the Microsoft kits still put a byte in the global namespace. The error did not surface under Qt because Qt does not put a byte in the global namespace.

There are several work-arounds discussed at std::byte on the Crypto++ wiki.

Incidentally, Microsoft kit code will break when it encounters a C++17 compiler and std::byte because of Microsoft's global byte. You will encounter the same error when using the Windows kits. Ironically, Microsoft employees authored C++ std::byte. Also see PR0298R0, A byte type definition.

jww
  • 97,681
  • 90
  • 411
  • 885
  • "Microsoft kits still put a byte in the global namespace" ... the way it's done in platform headers makes it very unlikely that they even can stop doing that. Doesn't look like it's going to change. Instead of using byte cryptopp should just use uint8_t – Pavel P Aug 13 '18 at 06:49
  • 1
    @Pavel - Crypto++ is no longer part of the problem since its byte is now scoped. The problem is solely Microsoft and their headers now. Hindsight being 20/20 Crypto++ should have not attempted to be compatible with Microsoft SDK headers. But the decision was made in 1995 and it was hard to change until the C++17 breaks came. – jww Aug 13 '18 at 06:52
  • ms headers don't care about c++ (why should they?) they, they are C after all. They have that byte type in many structures, and it's reasonable to typedef it as an unsigned char. I wouldn't say that "the problem is solely Microsoft and their headers". They might as well say the problem is in c++ or whatever. Note, I don't deal with crypto and never had that byte problem myself, just tried to look how they define it in headers and if there was a way to prevent that typedef. – Pavel P Aug 13 '18 at 06:56
  • 1
    @Pavel - Microsoft blaming C++ or C++ blaming Microsoft works for me. I don't have a dog in that fight. I'm fine with it as long as the problem is not with Crypto++. – jww Aug 13 '18 at 06:57
  • It's not in cryptopp also. However, since there was std::byte added, it makes sense to use std::byte, or to change internal code to use uint8_t if it doesn't match semantics of std::byte (to avoid future confusion). Also, just curious, if cryptopp also typedefed it as unsigned char, then there wouldn't be any problem IMO – Pavel P Aug 13 '18 at 07:00
  • 1
    @Pavel - `uint8_t` typedef is not a good choice for Crypto++. We support too many compilers and platforms. Some of the time we will be able to use `` and `uint8_t`; and other times `` will be missing and we will have to provide a `typedef`. Part of the appeal of `byte`, `word16`, `word32` and friends was avoiding that problem (until C++17 and the byte problem arrived). And I cringe when thinking about the problems of removing the symbol after 28 years. Users will want to tar and feather us. – jww Aug 13 '18 at 07:16
0

The first problem solved with changing byte* to CryptoPP::byte* :

CBC_Mode<AES>::Encryption encryptor((CryptoPP::byte*)szKey, AES::DEFAULT_KEYLENGTH, (CryptoPP::byte*)szInitVector);

But to solving the second problem (error LNK 2038) :

This is related to link error, Every body that using of crypto++ in Visual Studio may have this problem.

First I was download library from bellow link for visual studio in which containt .sln (VS Solution) :

  • https://www.cryptopp.com/#download

  • I build the library via Batch Build as cryptlib project in both state (Debug|Win32 and Release|Win32)

  • Because I used of Debug mode, I linked cryptlib.lib in cryptopp700\Win32\Output\Debug in dependencies section.
  • Also add dependencies for header files...

But I forgot something in project properties :

Finally, I set Runtime Library option to Multi-threaded Debug (/MTd)

This option is in :

  • Project Properties

  • Configuration Properties

  • C/C++

  • Code Generation

  • Runtime Library

0

I know this answer is not directly relating to Crypto++ & Windows SDK, but I know I found this while trying to figure out the same error when using the Nodejs addon library called Nan instead. I'm putting this answer here because it's in an accessible place for others who might run into similar issues to me.

I hadn't had too many issues compiling the project for a while but then ran into the same error as mentioned above. I wasn't using a byte symbol anywhere. There were dozens of errors pointing to libraries in the Windows SDK which also was conflicting with the cstddef header as the error addresses.

What I was able to do to fix the problem was rearranging the headers so that the Nan-related content (and any of my own header files that references it) was on top, above even the other standard C/C++ libraries. After that was done, the errors went away.

0

The decision is simpliest. Delete from your code 'using namespace std' and use namespace std:: before every operation instead.