Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5832915
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类: C/C++

2008-09-15 16:16:28

Introduction

The 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 . If the website is down, use , or use an archiving service such as archive.org .

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 . The Crypto++ users group can be found . The Crypto++ Wiki can be found . Finally, Dennis Bider has authored a User Guide and Help File which can be found . My most used reference is the source code, which can be found online at the and .

Windows CE

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

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

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 .

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 :

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 call SetNewAndDeleteFunctionPointers. 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 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, 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\.

From the Build Menu, Select Batch Build

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

Sample screenshot

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

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.

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.

Project Integration

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

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:

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

Additional (Unsupported) Configuration

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.

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.

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 :

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, (an ATL project which requires dynamic runtime linking) is using cryptlib.dynamic without dll.cpp.

Missing Adhoc.cpp

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 .

Compile Error 1001

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

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

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

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

Change the above to:

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.

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.

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

... then you should enable exception handling.

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.lib, msxml2.lib, etc ...

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

Link Error 1104

If you do not install MFC Unicode Library Versions (mfc42u.lib, mfc42ud.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.

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.

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.

To resolve this, 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

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 in Win32\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.

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

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

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 suffix and change the switch statement.

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.

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;

Crypto++ Integer

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

阅读(2719) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~