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