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