Crypto++
|
00001 #ifndef CRYPTOPP_DLL_ONLY 00002 #define CRYPTOPP_DEFAULT_NO_DLL 00003 #endif 00004 00005 #include "dll.h" 00006 00007 USING_NAMESPACE(CryptoPP) 00008 USING_NAMESPACE(std) 00009 00010 void FIPS140_SampleApplication() 00011 { 00012 if (!FIPS_140_2_ComplianceEnabled()) 00013 { 00014 cerr << "FIPS 140-2 compliance was turned off at compile time.\n"; 00015 abort(); 00016 } 00017 00018 // check self test status 00019 if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) 00020 { 00021 cerr << "Automatic power-up self test failed.\n"; 00022 abort(); 00023 } 00024 cout << "0. Automatic power-up self test passed.\n"; 00025 00026 // simulate a power-up self test error 00027 SimulatePowerUpSelfTestFailure(); 00028 try 00029 { 00030 // trying to use a crypto algorithm after power-up self test error will result in an exception 00031 AES::Encryption aes; 00032 00033 // should not be here 00034 cerr << "Use of AES failed to cause an exception after power-up self test error.\n"; 00035 abort(); 00036 } 00037 catch (SelfTestFailure &e) 00038 { 00039 cout << "1. Caught expected exception when simulating self test failure. Exception message follows: "; 00040 cout << e.what() << endl; 00041 } 00042 00043 // clear the self test error state and redo power-up self test 00044 DoDllPowerUpSelfTest(); 00045 if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) 00046 { 00047 cerr << "Re-do power-up self test failed.\n"; 00048 abort(); 00049 } 00050 cout << "2. Re-do power-up self test passed.\n"; 00051 00052 // encrypt and decrypt 00053 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}; 00054 const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; 00055 const byte plaintext[] = { // "Now is the time for all " without tailing 0 00056 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, 00057 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, 00058 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; 00059 byte ciphertext[24]; 00060 byte decrypted[24]; 00061 00062 CFB_FIPS_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_CFB; 00063 encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); 00064 encryption_DES_EDE3_CFB.ProcessString(ciphertext, plaintext, 24); 00065 00066 CFB_FIPS_Mode<DES_EDE3>::Decryption decryption_DES_EDE3_CFB; 00067 decryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); 00068 decryption_DES_EDE3_CFB.ProcessString(decrypted, ciphertext, 24); 00069 00070 if (memcmp(plaintext, decrypted, 24) != 0) 00071 { 00072 cerr << "DES-EDE3-CFB Encryption/decryption failed.\n"; 00073 abort(); 00074 } 00075 cout << "3. DES-EDE3-CFB Encryption/decryption succeeded.\n"; 00076 00077 // hash 00078 const byte message[] = {'a', 'b', 'c'}; 00079 const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D}; 00080 byte digest[20]; 00081 00082 SHA1 sha; 00083 sha.Update(message, 3); 00084 sha.Final(digest); 00085 00086 if (memcmp(digest, expectedDigest, 20) != 0) 00087 { 00088 cerr << "SHA-1 hash failed.\n"; 00089 abort(); 00090 } 00091 cout << "4. SHA-1 hash succeeded.\n"; 00092 00093 // create auto-seeded X9.17 RNG object, if available 00094 #ifdef OS_RNG_AVAILABLE 00095 AutoSeededX917RNG<AES> rng; 00096 #else 00097 // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs 00098 RandomNumberGenerator &rng(NullRNG()); 00099 #endif 00100 00101 // generate DSA key 00102 DSA::PrivateKey dsaPrivateKey; 00103 dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024); 00104 DSA::PublicKey dsaPublicKey; 00105 dsaPublicKey.AssignFrom(dsaPrivateKey); 00106 if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3)) 00107 { 00108 cerr << "DSA key generation failed.\n"; 00109 abort(); 00110 } 00111 cout << "5. DSA key generation succeeded.\n"; 00112 00113 // encode DSA key 00114 std::string encodedDsaPublicKey, encodedDsaPrivateKey; 00115 dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref()); 00116 dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref()); 00117 00118 // decode DSA key 00119 DSA::PrivateKey decodedDsaPrivateKey; 00120 decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref()); 00121 DSA::PublicKey decodedDsaPublicKey; 00122 decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref()); 00123 00124 if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3)) 00125 { 00126 cerr << "DSA key encode/decode failed.\n"; 00127 abort(); 00128 } 00129 cout << "6. DSA key encode/decode succeeded.\n"; 00130 00131 // sign and verify 00132 byte signature[40]; 00133 DSA::Signer signer(dsaPrivateKey); 00134 assert(signer.SignatureLength() == 40); 00135 signer.SignMessage(rng, message, 3, signature); 00136 00137 DSA::Verifier verifier(dsaPublicKey); 00138 if (!verifier.VerifyMessage(message, 3, signature, sizeof(signature))) 00139 { 00140 cerr << "DSA signature and verification failed.\n"; 00141 abort(); 00142 } 00143 cout << "7. DSA signature and verification succeeded.\n"; 00144 00145 00146 // try to verify an invalid signature 00147 signature[0] ^= 1; 00148 if (verifier.VerifyMessage(message, 3, signature, sizeof(signature))) 00149 { 00150 cerr << "DSA signature verification failed to detect bad signature.\n"; 00151 abort(); 00152 } 00153 cout << "8. DSA signature verification successfully detected bad signature.\n"; 00154 00155 // try to use an invalid key length 00156 try 00157 { 00158 ECB_Mode<DES_EDE3>::Encryption encryption_DES_EDE3_ECB; 00159 encryption_DES_EDE3_ECB.SetKey(key, 5); 00160 00161 // should not be here 00162 cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n"; 00163 abort(); 00164 } 00165 catch (InvalidArgument &e) 00166 { 00167 cout << "9. Caught expected exception when using invalid key length. Exception message follows: "; 00168 cout << e.what() << endl; 00169 } 00170 00171 cout << "\nFIPS 140-2 Sample Application completed normally.\n"; 00172 } 00173 00174 #ifdef CRYPTOPP_IMPORTS 00175 00176 static PNew s_pNew = NULL; 00177 static PDelete s_pDelete = NULL; 00178 00179 extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler) 00180 { 00181 s_pNew = pNew; 00182 s_pDelete = pDelete; 00183 } 00184 00185 void * __cdecl operator new (size_t size) 00186 { 00187 return s_pNew(size); 00188 } 00189 00190 void __cdecl operator delete (void * p) 00191 { 00192 s_pDelete(p); 00193 } 00194 00195 #endif 00196 00197 #ifdef CRYPTOPP_DLL_ONLY 00198 00199 int __cdecl main() 00200 { 00201 FIPS140_SampleApplication(); 00202 return 0; 00203 } 00204 00205 #endif