Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment
By Garth J Lancaster, Jeffrey Walton

Avoid common pitfalls when using Crypto++ and VC++

Introduction

The Crypto++ User Group occasionally receives questions on Crypto++ and Microsoft's Environments. The questions are usually basic such as, "VC++ can't find a header file - how [where] do I..." or more generic statements such as, "I can't compile." This article will attempt to resolve these common issues, and provide basic background information.

Source Code

The Crypto++ source code can be downloaded from the website at Crypto++ homepage. If the website is down, use the SourceForge page, or use an archiving service such as archive.org here.

Documentation

There are four sources of documentation for Crypto++. They are the Source Code, the Crypto++ Usenet Group, the Crypto++ FAQ, and the Crypto++ Wiki. Wei maintains an FAQ which can be found here. The Crypto++ users group can be found here. The Crypto++ Wiki can be found here. Finally, Dennis Bider has authored a User Guide and Help File which can be found here. My most used reference is the source code, which can be found online at the Crypto++ Library Reference Manual and Crypto++ Class Index.

Windows CE

Ugo Chirico maintains a port of Crypto++ 5.5.2 to Windows Mobile 2005 at Crypto++ 5.5.2 on Windows Mobile 2005. Dr. Chirico posts announcements to the Crypto++ user group. His initial post can be found at Crypto++ Users.

Managed Code

There are no special steps in using managed code. Note that if we are using the FIPS DLL, we might find that some functionality is missing (see the discussion below). For a well written example, see Mike Sinclair's CodeProject.com article, RSA Encryption with .NET 2.0 Cryptography Services and Crypto++ Wrapped as a Managed C++ Class Library.

FIPS Compliance

FIPS 140-2 certification means the library produces correct results and complies with certain cryptographic protocols. Protocols would include zeroing the memory of key material after the library is finished using it. When we refer to the FIPS compliant DLL, we will state FIPS DLL.

The FIPS DLL must be used in binary form as distributed by Wei (even though we have the source code and can build the same binary). This means we cannot build the Crypto++ DLL and claim it is FIPS compliant.

Version 5.5.2 is the last version of the library which Wei plans to submit for testing and validation. Details can be found here.

The module certification FAQ can be found under the Cryptographic Module Validation Program.

Single Threaded Versus Multi-threaded

In all cases, the Crypto++ library should be built using multi-threaded libraries. This was an issue with Visual C++ 6.0 and previous. At times, the Project Wizard would output a project using Singe Threaded project (/ML and /MLd).

Static Versus Dynamic Linking

C Runtime Library

When integrating Crypto++, the Crypto++ library must use the same runtime library linker setting as our Visual Studio project. The runtime library refers to the C Runtime Library. A stock Crypto++ distribution is built using static linking against the runtime (/MT and /MTd).

A default Visual Studio project created by the wizard will use dynamic runtime linking. The project would specify the /MD or /MDd linker switch for dynamic runtime linking, while the Crypto++ library would be using static linking (/MT or /MTd) from its build. This will cause a plethora of LINK2005 errors when linking. To resolve the Crypto++ library must be rebuilt. Table 1 below summarizes this discussion

Project Setting Project Link Switch Desired Runtime Linking Action Required
Static Runtime Linking /MT or /MTd Static None
Dynamic Runtime Linking /MD or /MDd Dynamic Rebuild Crypto++ Library

Rebuild Crypto++ Library means to rebuild the Crypto++ library after changing the settings to compile and link against dynamic versions of the runtime. Also see the section Unsupported Configuration below.

Static Runtime Linking

The Crypto++ library is distributed as a statically linked library. Static linking is usually preferred (versus the DLL or FIPS DLL). According to Wei Dai:

... there should not be any problems linking a DLL against a DLL. But using the static library saves on code size and I'd suggest it unless you need to use the DLL for some reason (such as FIPS compliance).

When creating a statically linked Visual Studio project, no additional settings need to be changed.

Dynamic Runtime Linking

When dynamically linking to the C Runtime (/MD or /MDd), the Crypto++ library must be rebuilt using the same link settings are the main project. Open the Crypto++ project and change the Crypto++ project setting for both Cryptlib and CryptDll. The settings should be changed to /MD or /MDd. For good measure, the setting should also be changed for Cryptest (and the validation test re-run: issue cryptest v).

Runtime Library Conflicts and the Crypto++ DLL/FIPS DLL

Runtime linking presents two difficult situations for the software author. First is the desire to link dynamically against the C runtime while using the FIPS DLL. The issue is derived as follows: Dynamic C Runtime linking is used by (/MD or /MDd) the application, but the distributed FIPS DLL is static (/MT or /MTd). The best solution is using the /NODEFAULTLIB switch, and hope that no runtime issues occur. This situation will create hard to track down runtime bugs and obscure initialization failures. Note that rebuilding the DLL using dynamic runtime linking is not available since we are using the FIPS DLL.

The second situation is created when using additional third party components. This includes MFC and ATL. Suppose we need to use the FIPS DLL. We change the Project settings to use the static version of the runtime, and link using the FIPS DLL. Next, we add the third party component which only offers dynamic linking against the C Runtime. We now have the situation previously described. The preferred work around it to contact the third party vendor, and acquire a library which uses the same runtime settings as our Project and Crypto++.

Unresolved External Symbols

When using the DLL or FIPS DLL, the newsgroup occasional receives reports of LNK2001 and LINK2019 such as below. This is because the DLL and FIPS DLL only includes certified algorithms. So the DLL exports AES, but it does not export DES (DES has been deprecated in various standards). Also missing from the FIPS DLL are supporting classes such as Base64Encoder.

Crypto.obj : error LNK2019: unresolved external symbol
"public: virtual void __thiscall CryptoPP::Base64Encoder::IsolatedInitialize
(class CryptoPP::NameValuePairs const &)"
(? IsolatedInitialize@Base64Encoder@CryptoPP@@UAEXABVNameValuePairs@2@@Z)
referenced in function "public: __thiscall CryptoPP::Base64Encoder::Base64Encoder
(class CryptoPP::BufferedTransformation *,bool,int)"
(??0Base64Encoder@CryptoPP@@QAE@PAVBufferedTransformation@1@_NH@Z)

or

dlltest.obj : error LNK2001: unresolved external symbol "__declspec(dllimport)
public: __thiscall CryptoPP::DH_Domainstruct CryptoPP::EnumToType
...

DLL_Debug/dlltest.exe : fatal error LNK1120: 1 unresolved externals

To resolve, first read the "MSVC-Specific Information" in the readme.txt. Wei offers two solutions to the issue:

There are two ways you can deal with this, either change Crypto++ to export those classes, by using CRYPTOPP_DLL macro, or link with both the DLL export library and a static library that contains the non-DLL classes and functions. The latter can be built by using the "DLL-Import" configuration of the cryptlib project.

Note that in Wei's first solution, we are rebuilding the DLL (not the FIPS DLL) to export the additional functions we require by using the CRYPTO_DLL macro. We may also have to add the source files to the cryptdll project in the solution. In the second offering, we are using the FIPS DLL and supplementing it with functionality from Crypto++'s static library, since the FIPS DLL does not contain all the Crypto++ functionality we need.

Crypto++ Dll - New and Delete

At time, we might have to force Crypto++ to use new and delete from another library rather than the standard runtime. For this, we would want to callSetNewAndDeleteFunctionPointers. See dll.cpp for Wei's use of setting the function pointers for the standard runtime.

Also be aware that this usually has to be done early in the initialization process. This creates additional issues not related to Crypto++, such as linking libraries in the wrong order. Please see Knowledge Base Article 148652, LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++.

Compiling Crypto++

Visit the Crypto++ homepage and fetch a version for download. This article is based on version 5.2.1, but any version should do. We should review the "Platforms" Matrix when choosing a Crypto++ distribution. When using Visual Studio 6.0, Microsoft's Processor Pack is recommended for Crypto++ 5.1 and earlier; and is required for Crypto++ 5.2 and later.

Create a directory on the hard drive for the distribution of Crypto++ downloaded. Locate the cryptest.dsw or cryptest.sln file, and open it. In this example, the ZIP file was extracted to C:/CryptoPP 5.2.1/.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第1张图片

From the Build Menu, Select Batch Build

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第2张图片

For the purposes of this article, build only the Static Library by un-checking the appropriate selections.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第3张图片

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第4张图片

Integrating Crypto++ into the Visual C++ Environment

This document will add the library to the Visual Studio environment rather than the Project environment. This means the settings affect every project, not just a Crypto++ project. Please see John Deters's comment below for reasons not to do so. It is well crafted and explained commentary which should prove useful. Once the build is complete, drill into the C:/CryptoPP 5.2.1/Debug/ folder. Rename the library file from cryptlib.lib to cryptlibd.lib (notice the addition of the "d" for Debug).

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第5张图片

Move the Debug Library to the location of the Header and Source Files. In this example, the location is C:/CryptoPP 5.2.1/. Also, move (without renaming) the Release version to the same folder.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第6张图片

Visual C++ Integration

Add the location of the Header Files, Source Files, and Libraries to the VC++ Environment. Select Tools | Options, Directories Tab. Make the appropriate entry for the previously mentioned items in the drop down menu.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第7张图片

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第8张图片

Project Integration

Add the location of the Header Files, Source Files, and Libraries to the VC++ Project.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第9张图片

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第10张图片

This step will allow us to #include"ecp.h", rather than including ecp.h, all of its dependencies; and specifying full or relative paths. Also, since the Library is on path (and appropriately named), one can now issue the following #pragma to have the linker include the library:

minus.gif  Collapse
// Crypto++ Library
#ifdef _DEBUG
#  pragma comment ( lib, "cryptlibd" )
#else
#  pragma comment ( lib, "cryptlib" )
#endif

Additional (Unsupported) ConfigurationCompiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第11张图片

If interested, a project configuration exists which allows for building Crypto++ using both static and dynamic runtime linking. However, don't expect Wei to support it. The authors have used it for quite some time with both Visual Studio 8.0 and Visual Studio 9.0.

  • Visual Studio 8.0 Alternate Configuration
  • Visual Studio 9.0 Alternate Configuration

Unfortunately, the x64 build settings have been removed by the IDE because the x64 compiler and headers were not installed during installation. Fortunately, they can be easily added back into the project using the Configuration Manager.

The alternate configuration renames the cryptlib project to cryptlib.static. It also adds cryptlib.dynamic (with settings copied form cryptlib.static). Both the static and dynamic projects build debug and release libraries. ".dynamic" and ".static" were chosen rather than 'd' and 's' suffixes so that debug builds would not be confused with dynamic c runtime linking builds. Files offered by the configurations are:

  • cryptlib.static.lib
  • cryptlibd.static.lib
  • cryptlib.dynamic.lib
  • cryptlibd.dynamic.lib

To use the configuration, unzip the files over top of the Crypto++ files, replacing as required. For those who concern themselves with library size (before the linker removes unused functions), dynamic runtime linking produces considerably smaller code.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第12张图片

After building the four variant, use copylib.cmd to copy the libraries to the root of the Crypto++ distibution. Finally, include CryptlibInclude.h in the project.CryptlibInclude.h performs a switch based on _DLL (defined when using dynamic runtime linking) and DEBUG :

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第13张图片

Also note that both the static and dynamic libraries use dll.cpp, even though we are not building the dll . If we don't use dll.cpp, we will receive LNK2001 errors stsing that a function (using _thiscall) could not be found, despite the fact that we specify _cdecl for compilation in the source file's properties. Below,VerifyHash (an ATL project which requires dynamic runtime linking) is using cryptlib.dynamic without dll.cpp.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第14张图片

We receive 20 errors (10 pairs) similar to below. The first error claims that the program cannot be linked because of a missing function in VerifyHash.obj. The second (referring to the same function) claims the function cannot be found in the Crypto++ library.

VerifyHash.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::IteratedHashBase::Update(unsigned char const *,unsigned int)" (?Update@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UAEXPBEI@Z)

cryptlibd.dynamic.lib(md5.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::IteratedHashBase::Update(unsigned char const *,unsigned int)" (?Update@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UAEXPBEI@Z)

I can't explain why functions from iterbase.h and iterbase.cpp are affected by inclusion or exclusion of dll.cpp.

Common Errors

This section will discuss common compiler and liner errors encountered when using the Crypto+ library. They are usually encountered because of an oversight in following these instructions. Once you have verified that these instructions were followed, please post your question to the Crypto++ User Group.

Compile Error 1001

If you receive Internal Compile Error COMPILE 1001 (C1001) shown below

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第15张图片

You should perform the following:

  • Verify your Source Code is correct
  • Verify config.h (see below)
  • Rearrange Functions (note the CL Error will output the Source Code line where the Compiler encountered problems - see below)
  • Disable Precompiled Headers
  • Update the Library
  • Update the Compiler
  • Post to the Crypto++ Newsgroup
  • Contact Microsoft Support

Verify config.h

Depending on the version of Visual Studio, some compile time changes are invoked. One suspect to pay particular attention to is _MSC_VER < 1300. If using Visual Studio 7.1 or above, changing to below may do the trick.

minus.gif  Collapse
// how to declare class constants
#if defined(_MSC_VER) && _MSC_VER <= 1300
#  define CRYPTOPP_CONSTANT(x) enum {x};

#else
#  define CRYPTOPP_CONSTANT(x) static const int x;
#endif

Rearrange Functions

minus.gif  Collapse
Function A
   { ... }
Function B
   { ... }

Change the above to:

minus.gif  Collapse
Function B
   { ... }
Function A
   { ... }

I can't explain this one, but it has worked for me in the past when working with Crypto++ Elliptic Curve functions.

Compile Error 1083

If you do not add the path to the Crypto++ header files to the Visual C++ environment or your Project, COMPILE 1083 (C1083) Errors similar to below will be displayed.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第16张图片

Compile Error 1189

If you incorrectly match the C Runtime with MFC (for example, MFC as a DLL, Crypto++ and C Runtime as a Static Library), COMPILE 1189 (C1189), errors similar to those below will be displayed.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第17张图片

You should revisit the section Static Versus Dynamic Linking. MFC uses dynamic runtime linking.

Compile Warning 4530

If you receive Compile Warning COMPILE 4530 (C4530) ...

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第18张图片

... then you should enable exception handling.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第19张图片

Link Error 1103

If you receive LINK 1103 (LNK1103) "debugging information corrupt" when using Visual C++ 6.0 and the latest Platform SDK (shown below) with libraries uuid.lib,shell32.libmsxml2.lib, etc ...

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第20张图片

... then you should roll back the Platform SDK to February 2003. One may be able to change the directory order in Visual C++ 6.0.

CryptoDirectoriesVC6.png

Link Error 1104

If you do not install MFC Unicode Library Versions (mfc42u.libmfc42ud.lib, etc.), but define UNICODE, LINK 1104 (LNK1104), then errors similar to those below will be displayed. This is a Visual C++ 6.0 and previous error, since Visual Studio 7.0 and above do not allow a non-Unicode installation.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第21张图片

To resolve, rerun setup and install the Unicode Libraries (performing a custom installation).

Link Error 1104

If you do not place the Crypto++ Library on the VC++ IDE path, LINK 1104 (LNK1104), then errors similar to those below will be displayed.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第22张图片

Link Error 2001

If you do not link the Crypto++ Library to the project, LINK 2001 (LNK2001), errors similar to those below will be displayed.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第23张图片

To resolve this, add the following to StdAfx.h (if using precompiled headers) or to the source file using Crypto++.

minus.gif  Collapse
// Crypto++ Library
#ifdef _DEBUG
#  pragma comment ( lib, "cryptlibd" )
#else
#  pragma comment ( lib, "cryptlib" )
#endif

Alternately, one can add the Crypto++ Library through the Visual C++ IDE.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第24张图片

Link Error 2001

The Crypto++ output libraries are located at Win32/output/debug/cryptlib.lib and Win32/output/release/cryptlib.lib. The DLL and its export library are inWin32/dll_output. Note the "dll_" in the path name. Verify that you are using the correct paths.

Link Error 2005

If you do not change C Runtime Library settings on the Project, LINK 2005 (LNK2005), then errors similar to those below will be displayed.

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第25张图片

You should use the Multithreaded versions of the C++ Runtime Library:

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第26张图片

Link Error 2005 When Using ATL

Should you encounter LNK2005 when using ATL, recompile the Crypto++ library using the Multithreaded DLL and Multithreaded Debug DLL choices of the runtime library. This was not an issue in Visual C++ 6.0, but it is an issue in Visual Studio 2005.

Link Error 2019 When Using the FIPS DLL

This error is due to the FIPS DLL only exporting certified algorithms such as AES. Wei offers two solutions to the issue. First, you can statically link against the library. Second, you must use the DLL version of the library (not the FIPS DLL). Then, to export the missing classes of interest, add the CRYPTOPP_DLL macro to the class declaration. Then rebuild the DLL-Import project.

Integer Class std::cout Formatting

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第27张图片

As distributed, the Integer class displays a suffix ('o', '.', or 'h') to denote base. In addition, the library uses uppercase characters for all hexadecimal output. To change the behavior so that Integer does not use a suffix and honors ios::uppercase flag, perform the following. First, remove the declaration for suffixand change the switch statement.

minus.gif  Collapse
switch(f)
{
  case std::ios::oct :
    base = 8;
    block = 8;
    break;
  case std::ios::hex :
    base = 16;
    block = 4;
    break;
  default :
    base = 10;
    block = 3;
}

Next, add the following.

minus.gif  Collapse
const char* vec = NULL;
const char upper[]="0123456789ABCDEF";
const char lower[]="0123456789abcdef";

if( out.flags() & (long)std::ios::uppercase )
{ vec = upper; }
else
{ vec = lower; }

...

// No longer can return out << suffix;
return out;

Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment_第28张图片

Revisions

  • 07.08.2008 Added link to NIST certification FAQ
  • 05.27.2008 Added Adhoc.cpp Information
  • 05.27.2008 Added Dr. Chirico's Windows CE port
  • 05.25.2008 Removed HashFilter AlgorithmName() fix
  • 05.25.2008 Added Alternate Configuration (Static and Dynamic C Runtime Projects)
  • 04.20.2008 Added Alternate Website and Download Links
  • 03.21.2008 Added Managed Code Section
  • 02.22.2008 Added Link Error 2019 (LNK2019)
  • 02.22.2008 Added information on CRYPTOPP_DLL macro
  • 11.29.2007 Added Single versus Multi-Threaded
  • 11.28.2007 Added FIPS Compliance Section
  • 11.28.2007 Reworked Static versus Dynamic Linking Section
  • 11.28.2007 Removed Sample Project
  • 06.04.2007 Added Link Error 2005 when using ATL (LNK2005)
  • 12.31.2006 Added Crypto++ Wiki Site Link
  • 12.27.2006 Updated Crypto++ Class and Library Reference (Crypto++ 5.4 Release)
  • 12.23.2006 Added Additional Fix to Internal Compiler Error (C1001)
  • 12.22.2006 Added Link to Chris Deter's Comments
  • 12.22.2006 Added Startup Project Information
  • 12.17.2006 Added Link Error 1103 (LNK1103)
  • 12.15.2006 Updated Article Graphics
  • 12.13.2006 Added HashFilter AlgorithName()
  • 12.13.2006 Added FAQ, User Guide, and Crypto++ user Newsgroup
  • 12.12.2006 Added Compile Warning 4530
  • 12.11.2006 Added VC7 Directories Dialog
  • 12.09.2006 Added Unicode Library Installation
  • 12.09.2006 Added Additional Fix Internal Compiler Error (C1001)
  • 11.21.2006 Added Internal Compiler Error (C1001)
  • 11.16.2006 Added Integer std::cout Formatting
  • 11.15.2006 Added Static versus Dynamic Crytpo++ Linking
  • 11.14.2006 Initial Release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

Garth J Lancaster



Occupation: Team Leader
Location: Australia Australia

Jeffrey Walton

%7B49D920C6-4CF4-49D1-AE77-D5D16BAB8849%7D.jpg

Mvp
Currently I am providing services as a private consultant. In the past, I have worked as an both an IT contractor and IT consultant for County Government (Anne Arundel County, MD), the Nuclear Energy Institute, the Treasury Department, and Social Security Administration. Primary roles with the Federal Government were Network Engineer and System Administrator. Administration experience is dominated by Microsoft Windows and includes Novell NetWare, with additional exposure and familiarity with Mac and Linux OS's.

An undergraduate degree (Bachelor of Science, Computer Science) was obtained from University of Maryland. Graduate work includes a Masters of Science (Computer Science) from Johns Hopkins University (expected in the near future).

Training and Certifications include CISSP, Microsoft, Checkpoint, and Cisco.

In addition to the Networking experience, I am a principal partner in an IT adventure specializing in Tamper Sensitive and Tamper Resistant software.

In what's left of spare time I enjoy reading, spinning my Rubiks Cube, and researching the factorization of RSA Moduli (the Integer Factorization Problem).
Occupation: Systems / Hardware Administrator
Location: United States United States

Other popular Programming Tips articles:

  • Programming Self-generating Code for Windows Applications
    Executing VC++ codes in STACK or HEAP
  • 10 Minutes to document your code
    Setting up doxygen, a free tool to document your code, in a few simple steps.
  • Optimization: Your Worst Enemy
    Learn about the potential pitfalls of code optimization.
  • How to use google and other tips for finding programming help
    A primer for people looking to learn to help themselves find answers to programming questions
  • Aggressive Optimizations for Visual C++
    Save time and space in your release builds - fight bloatware!

你可能感兴趣的:(Openssl,&,cryptlib研究)