Crypto++  5.6.3
Free C++ class library of cryptographic schemes
dlltest.cpp
1 #ifndef CRYPTOPP_DLL_ONLY
2 # define CRYPTOPP_DEFAULT_NO_DLL
3 #endif
4 
5 #include "dll.h"
6 #include "cryptlib.h"
7 #include "filters.h"
8 
9 USING_NAMESPACE(CryptoPP)
10 USING_NAMESPACE(std)
11 
12 void FIPS140_SampleApplication()
13 {
15  {
16  cerr << "FIPS 140-2 compliance was turned off at compile time.\n";
17  abort();
18  }
19 
20  // check self test status
22  {
23  cerr << "Automatic power-up self test failed.\n";
24  abort();
25  }
26  cout << "0. Automatic power-up self test passed.\n";
27 
28  // simulate a power-up self test error
30  try
31  {
32  // trying to use a crypto algorithm after power-up self test error will result in an exception
33  AES::Encryption aes;
34 
35  // should not be here
36  cerr << "Use of AES failed to cause an exception after power-up self test error.\n";
37  abort();
38  }
39  catch (SelfTestFailure &e)
40  {
41  cout << "1. Caught expected exception when simulating self test failure. Exception message follows: ";
42  cout << e.what() << endl;
43  }
44 
45  // clear the self test error state and redo power-up self test
48  {
49  cerr << "Re-do power-up self test failed.\n";
50  abort();
51  }
52  cout << "2. Re-do power-up self test passed.\n";
53 
54  // encrypt and decrypt
55  const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
56  const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
57  const byte plaintext[] = { // "Now is the time for all " without tailing 0
58  0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
59  0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
60  0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20};
61  byte ciphertext[24];
62  byte decrypted[24];
63 
64  CFB_FIPS_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_CFB;
65  encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv);
66  encryption_DES_EDE3_CFB.ProcessString(ciphertext, plaintext, 24);
67 
68  CFB_FIPS_Mode<DES_EDE3>::Decryption decryption_DES_EDE3_CFB;
69  decryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv);
70  decryption_DES_EDE3_CFB.ProcessString(decrypted, ciphertext, 24);
71 
72  if (memcmp(plaintext, decrypted, 24) != 0)
73  {
74  cerr << "DES-EDE3-CFB Encryption/decryption failed.\n";
75  abort();
76  }
77  cout << "3. DES-EDE3-CFB Encryption/decryption succeeded.\n";
78 
79  // hash
80  const byte message[] = {'a', 'b', 'c'};
81  const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D};
82  byte digest[20];
83 
84  SHA1 sha;
85  sha.Update(message, 3);
86  sha.Final(digest);
87 
88  if (memcmp(digest, expectedDigest, 20) != 0)
89  {
90  cerr << "SHA-1 hash failed.\n";
91  abort();
92  }
93  cout << "4. SHA-1 hash succeeded.\n";
94 
95  // create auto-seeded X9.17 RNG object, if available
96 #ifdef OS_RNG_AVAILABLE
98 #else
99  // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs
101 #endif
102 
103  // generate DSA key
104  DSA::PrivateKey dsaPrivateKey;
105  dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024);
106  DSA::PublicKey dsaPublicKey;
107  dsaPublicKey.AssignFrom(dsaPrivateKey);
108  if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3))
109  {
110  cerr << "DSA key generation failed.\n";
111  abort();
112  }
113  cout << "5. DSA key generation succeeded.\n";
114 
115  // encode DSA key
116  std::string encodedDsaPublicKey, encodedDsaPrivateKey;
117  dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref());
118  dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref());
119 
120  // decode DSA key
121  DSA::PrivateKey decodedDsaPrivateKey;
122  decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref());
123  DSA::PublicKey decodedDsaPublicKey;
124  decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref());
125 
126  if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3))
127  {
128  cerr << "DSA key encode/decode failed.\n";
129  abort();
130  }
131  cout << "6. DSA key encode/decode succeeded.\n";
132 
133  // sign and verify
134  byte signature[40];
135  DSA::Signer signer(dsaPrivateKey);
136  assert(signer.SignatureLength() == 40);
137  signer.SignMessage(rng, message, 3, signature);
138 
139  DSA::Verifier verifier(dsaPublicKey);
140  if (!verifier.VerifyMessage(message, 3, signature, sizeof(signature)))
141  {
142  cerr << "DSA signature and verification failed.\n";
143  abort();
144  }
145  cout << "7. DSA signature and verification succeeded.\n";
146 
147 
148  // try to verify an invalid signature
149  signature[0] ^= 1;
150  if (verifier.VerifyMessage(message, 3, signature, sizeof(signature)))
151  {
152  cerr << "DSA signature verification failed to detect bad signature.\n";
153  abort();
154  }
155  cout << "8. DSA signature verification successfully detected bad signature.\n";
156 
157  // try to use an invalid key length
158  try
159  {
160  ECB_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_ECB;
161  encryption_DES_EDE3_ECB.SetKey(key, 5);
162 
163  // should not be here
164  cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n";
165  abort();
166  }
167  catch (InvalidArgument &e)
168  {
169  cout << "9. Caught expected exception when using invalid key length. Exception message follows: ";
170  cout << e.what() << endl;
171  }
172 
173  cout << "\nFIPS 140-2 Sample Application completed normally.\n";
174 }
175 
176 #ifdef CRYPTOPP_IMPORTS
177 
178 static PNew s_pNew = NULL;
179 static PDelete s_pDelete = NULL;
180 
181 extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler)
182 {
183  s_pNew = pNew;
184  s_pDelete = pDelete;
185 }
186 
187 void * __cdecl operator new (size_t size)
188 {
189  return s_pNew(size);
190 }
191 
192 void __cdecl operator delete (void * p)
193 {
194  s_pDelete(p);
195 }
196 
197 #endif
198 
199 #ifdef CRYPTOPP_DLL_ONLY
200 
201 int __cdecl main()
202 {
203  FIPS140_SampleApplication();
204  return 0;
205 }
206 
207 #endif
The self tests were executed via DoPowerUpSelfTest() or DoDllPowerUpSelfTest(), and the result was su...
Definition: fips140.h:47
An invalid argument was detected.
Definition: cryptlib.h:182
const char * what() const
Retrieves a C-string describing the exception.
Definition: cryptlib.h:166
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: asn.cpp:524
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: asn.cpp:539
Abstract base classes that provide a uniform interface to this library.
STL namespace.
Interface for random number generators.
Definition: cryptlib.h:1186
bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
Definition: fips140.cpp:29
Exception thrown when a crypto algorithm is used after a self test fails.
Definition: fips140.h:23
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: pubkey.h:1243
SHA-1
Definition: sha.h:21
void SimulatePowerUpSelfTestFailure()
Sets the power-up self test status to POWER_UP_SELF_TEST_FAILED.
Definition: fips140.cpp:34
void DoDllPowerUpSelfTest()
Performs the power-up self test on the DLL.
Definition: fipstest.cpp:599
Automatically Seeded X9.17 RNG.
Definition: osrng.h:178
RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
Definition: cryptlib.cpp:406
String-based implementation of Store interface.
Definition: filters.h:1066
PowerUpSelfTestStatus GetPowerUpSelfTestStatus()
Provides the current power-up self test status.
Definition: fips140.cpp:39
Implementation of BufferedTransformation's attachment interface.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: pubkey.h:1255
Crypto++ library namespace.
virtual void Final(byte *digest)
Computes the hash of the current message.
Definition: cryptlib.h:954
Functions and definitions required for building the FIPS-140 DLL on Windows.
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2030