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

Introduction

The Crypto++ mailing list occasionally receives questions on Crypto++ and Microsoft’s IDE Environments. The questions are usually basic questions 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.

Wei Dai maintains a FAQ. Additionally, Dennis Bider has authored a User Guide and Help File. The author’s most used references are the Crypto++ Library Reference Manual and Crypto++ Class Index.

It is the author’s personal opinion that this does not constitute an article per se. It is a basic building block to more advanced articles, and a convenient point of editing as Crypto++ and Microsoft Visual Studio evolve.

The sample project exercises the Crypto++ pseudo random number generator. It verifies correctness of the VC++ Integration.

Static versus Dynamic Linking

This article presents Static Linking to Crypto++. There are small differences in the Crypto++ Library, depending on which version the reader chooses to link against. The most notable is the lack of DES support in the DLL. Since NIST withdrew DES as an approved federal standard in May, 2005 (see Federal Register, Volume 70, No. 96), DES is not avalable in the Crypto++ DLL Library.

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).

If the reader chooses to use Dynamic Linking, it should be applied to all libraries in the project: MFC, C Runtime, and Crypto++. This also includes third-party STL libraries such as Dinkumware.

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

Visit the Crypto++ Homepage and fetch a version for download. This article is based on version 5.2.1. Note that Crypto++ Library versions 5.0.4 and 5.2.3 have been validated by NIST and CSE for FIPS 140-2 Level 1 Conformance. To enjoy Level 1 Conformance, one must use the DLL version of the Library.

The reader is encouraged to review the Platforms Matrix when choosing a Crypto++ distribution. At this point, Microsoft’s Processor Pack is recommended for Crypto++ 5.0 and 5.1, and is required for Crypto++ 5.2.

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

From the Build Menu, Select Batch Build.

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

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).

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.

Finally, 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.

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

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

Crypto++ uses routines from the C Runtime. Readers’ projects are required to use the same settings to avert linker errors. When creating a new project, be sure to select Multithreaded Runtime Libraries. Once a project is created, select the appropriate C Runtime Library under Project | Settings, C++ Tab, Code Generation Category. Do this for both Debug and Release builds of the project.

Compile Error 1001

If the reader receives Internal Compile Error COMPILE 1001 (C1001) (shown below),

one should perform the follwing:

  • Verify the Source Code is correct
  • Rebuild the Library with Optimizations Disabled (Project | Settings, C++ Tab, General Settings)
  • Rearrange Functions (note the CL Error will output the Source Code line where the Compiler encountered problems—see below)
  • Update the Library
  • Update the Compiler
  • Contact Microsoft Support
Function A
   { ... }
Function B
   { ... }

Change the above to:

Function B
   { ... }
Function A
   { ... }

Compile Error 1083

If the reader does not add the path to the Crypto++ header files to the Visual C++ environment, COMPILE 1083 (C1083) Errors similar to what is shown below will be displayed.

Compile Error 1189

If the reader incorrectly matches 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 the one below will be displayed.

The reader should choose the static version of the MFC Library, as shown below.

Link Error 1104

If the reader does not place the Crypto++ Library on the VC++ IDE path, LINK 1104 (LNK1104) Errors similar to what you see below will be displayed.

Link Error 2001

If the reader does not link the Crypto++ Library to the project, LINK 2001 (LNK2001) Errors similar to what’s shown below will be displayed.

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

// 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.

Link Error 2001

Verify one is linking against the Static version of the Library. The static libraries are Win32\output\debug\cryptlib.lib and Win32\output\release\cryptlib.lib. The DLL and its exports library are in Win32\dll_output. Note the “dll_” in the path name.

Link Error 2005

If the reader does not change C Runtime Library settings, LINK 2005 (LNK2005) Errors similar to the one below will be displayed.

Changing Integer Class std::cout Formatting

To remove the trailing decimal point, edit Integer.cpp:

// operator<< Line 3357 of Integer.cpp
std::ostream& operator<<(std::ostream& out, const Integer& a)
{
   // Get relevant conversion specifications from ostream.
   long f = out.flags() & std::ios::basefield;
   int base, block;
   char suffix;

   ...

   // suffix = '';  will not compile
   // suffix = '\0'; has side effects
   //   for example:
   // std::cout << Integer("123456789") << std::endl;

   // Change return out << suffix; to the following
   if( 10 != base ) {
      return out << suffix;
   } else {
      return out;
   }
}

HashFilter AlgorithmName()

Currently, the HashFilter emits ‘unknown’ as a response to AlgorithmName().

MD5 hashMD5;
HashFilter filterMD5(hashMD5);
...
filterMD5.TransferTo( encoder );
cout << filterMD5.AlgorithmName() << ": " << digest << endl;
digest.erase();

To retrieve the hash’s name, add the following to HashFilter in filters.h:

std::string AlgorithmName() const { return m_hashModule.AlgorithmName(); }

Revisions

  • 12-14-2006 Added FAQ Reference
  • 12-14-2006 Added Dennis Bider’s User Guide
  • 12-14-2006 Added Additional Link 2001 Error
  • 12-14-2006 Added HashFilter AlgorithmName()
  • 11-24-2006 Added CL1001 Error
  • 11-16-2006 Added Integer std::cout Formatting
  • 11-15-2006 Added Static versus Dynamic Crytpo++ Linking
  • 11-14-2006 Initial Release

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read