13 #if defined( __MVS__ ) || defined( __VMCMS__ )
15 #pragma convlit( suspend )
17 #if defined( __ILEC400__ )
22 #define max( a, b ) ( ( ( a ) > ( b ) ) ? ( ( int ) a ) : ( ( int ) b ) )
31 #if defined( TEST_MIDLEVEL ) || defined( TEST_HIGHLEVEL )
35 static int compareSessionKeys(
const CRYPT_CONTEXT cryptContext1,
44 "\x00\x00\x00\x00\x00\x00\x00\x00"
45 "\x00\x00\x00\x00\x00\x00\x00\x00", ivSize );
47 "\x00\x00\x00\x00\x00\x00\x00\x00"
48 "\x00\x00\x00\x00\x00\x00\x00\x00", ivSize );
49 memcpy( buffer,
"0123456789ABCDEF",
max( blockSize, 8 ) );
53 printf(
"cryptEncrypt() with first key failed with error "
54 "code %d, line %d.\n", status, __LINE__ );
60 printf(
"cryptDecrypt() with second key failed with error "
61 "code %d, line %d.\n", status, __LINE__ );
64 if( memcmp( buffer,
"012345678ABCDEF",
max( blockSize, 8 ) ) )
66 puts(
"Data decrypted with key2 != plaintext encrypted with key1." );
88 const BOOLEAN useSidechannelProtection,
98 BYTE buffer[ 1024 ], hashBuffer[] =
"abcdefghijklmnopqrstuvwxyz";
101 printf(
"Testing %s%s digital signature%s...\n",
103 useSidechannelProtection ?
" with side-channel protection" :
"" );
119 signContext = externalSignContext;
120 checkContext = externalCheckContext;
160 signContext, hashContext, extraData );
163 printf(
"cryptCreateSignature() failed with error code %d, line %d.\n",
167 printf(
"cryptCreateSignature() reports signature object will be %d "
168 "bytes long\n", length );
169 assert( length <= 1024 );
172 if( useSidechannelProtection )
180 signContext, hashContext, extraData );
183 printf(
"cryptCreateSignature() failed with error code %d, line %d.\n",
187 if( useSidechannelProtection && value != 1 )
197 printf(
"cryptQueryObject() failed with error code %d, line %d.\n",
201 printf(
"cryptQueryObject() reports object type %d, algorithm %d, "
202 "hash algorithm %d.\n", cryptObjectInfo.
objectType,
209 useSHA2 ?
"sigr2" :
"sigr", buffer, length );
214 "sigr.pgp" :
"sigd.pgp", buffer, length );
228 printf(
"cryptCheckSignature() failed with error code %d, line %d.\n",
237 printf(
"Generation and checking of %s digital signature succeeded.\n\n",
242 static int keyExportImport(
const char *algoName,
256 printf(
"Testing %s%s public-key export/import...\n",
285 cryptContext = externalCryptContext;
286 decryptContext = externalDecryptContext;
300 sessionKeyContext1 );
303 printf(
"cryptExportKeyEx() failed with error code %d, line %d.\n",
307 printf(
"cryptExportKeyEx() reports exported key object will be %d "
308 "bytes long\n", length );
309 if( ( buffer = malloc( length ) ) == NULL )
314 cryptContext, sessionKeyContext1 );
317 printf(
"cryptExportKeyEx() failed with error code %d, line %d.\n",
327 printf(
"cryptQueryObject() failed with error code %d, line %d.\n",
332 printf(
"cryptQueryObject() reports object type %d, algorithm %d.\n",
337 "keytrans" :
"keytr_el", buffer, length );
340 "keytrans.pgp" :
"keytr_el.pgp", buffer, length );
348 sessionKeyContext2, NULL );
351 printf(
"cryptImportKeyEx() failed with error code %d, line %d.\n",
358 if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
365 printf(
"Export/import of session key via %d-bit %s-encrypted data "
377 const size_t length = ( INT_MAX <= 32768L ) ? 16384 : 1048576;
380 puts(
"Testing encryption of large data quantity..." );
383 if( ( buffer = malloc( length ) ) == NULL )
385 printf(
"Couldn't allocate buffer of %ld bytes, skipping large "
386 "buffer encryption test.\n", (
long ) length );
389 memset( buffer,
'*', length );
400 "\x00\x00\x00\x00\x00\x00\x00\x00", 8 );
404 printf(
"cryptEncrypt() of large data quantity failed with error "
405 "code %d, line %d.\n", status, __LINE__ );
420 "\x00\x00\x00\x00\x00\x00\x00\x00", 8 );
424 printf(
"cryptDecrypt() of large data quantity failed with error "
425 "code %d, line %d.\n", status, __LINE__ );
432 for( i = 0; i < ( int ) length; i++ )
434 if( buffer[ i ] !=
'*' )
436 printf(
"Decrypted data != original plaintext at position %d, "
437 "line %d.\n", i, __LINE__ );
445 printf(
"Encryption of %ld bytes of data succeeded.\n\n",
453 static int deriveKey(
const C_STR userKey,
const int userKeyLength,
470 "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
472 "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
484 userKey, userKeyLength );
487 printf(
"Key derivation failed with error code %d, line %d.\n",
493 userKey, userKeyLength );
496 printf(
"Key derivation failed with error code %d, line %d.\n",
502 if( !compareSessionKeys( cryptContext, decryptContext ) )
515 C_STR medUserKey =
TEXT(
"This is a long user key for key derivation testing" );
516 C_STR longUserKey =
TEXT(
"This is a really long user key that exceeds the HMAC input limit for keys" );
520 puts(
"Testing key derivation..." );
540 printf(
"Failed to get/set context attribute via equivalent global "
541 "attribute, error\ncode %d, value %d (should be 5), line "
542 "%d.\n", status, value, __LINE__ );
569 "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
574 memset( buffer, 0, 8 );
577 if( memcmp( buffer,
"\x9B\xBD\x78\xFC\x11\xA3\xA9\x08", 8 ) )
579 puts(
"Derived key value doesn't match predefined test value." );
583 puts(
"Key exchange via derived key succeeded.\n" );
620 typedef enum { AES_NONE, AES_128_128, AES_128_256,
621 AES_256_128, AES_256_256 } AES_KEYSIZE_OPT;
625 static int conventionalExportImport(
const CRYPT_CONTEXT cryptContext,
629 const AES_KEYSIZE_OPT aesKeysizeOpt )
634 const C_STR userKey =
TEXT(
"All n-entities must communicate with other n-entities via n-1 entiteeheehees" );
640 "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
647 userKey, userKeyLength );
650 printf(
"cryptSetAttributeString() failed with error code %d, line "
651 "%d.\n", status, __LINE__ );
657 sessionKeyContext1 );
660 printf(
"cryptExportKey() failed with error code %d, line %d.\n",
664 printf(
"cryptExportKey() reports exported key object will be %d bytes "
666 if( ( buffer = malloc( length ) ) == NULL )
671 sessionKeyContext1 );
674 printf(
"cryptExportKey() failed with error code %d, line %d.\n",
684 printf(
"cryptQueryObject() failed with error code %d, line %d.\n",
689 printf(
"cryptQueryObject() reports object type %d, algorithm %d, mode "
692 if( aesKeysizeOpt == AES_NONE )
696 const char *
fileName = ( aesKeysizeOpt == AES_128_128 ) ? \
698 ( aesKeysizeOpt == AES_128_256 ) ? \
700 ( aesKeysizeOpt == AES_256_128 ) ? \
701 "kek_aes256_128" :
"kek_aes256_256";
706 printf(
"Key wrap with algorithm CRYPT_ALGO_HMAC_SHA2 reported "
707 "hash algorithm as %d, line %d.\n", status, __LINE__ );
717 printf(
"cryptCreateContext() failed with error code %d, line %d.\n",
726 cryptObjectInfo.
salt,
733 ( aesKeysizeOpt == AES_128_256 || aesKeysizeOpt == AES_256_256 ) )
747 userKey, userKeyLength );
750 printf(
"cryptSetAttributeString() failed with error code %d, line "
751 "%d.\n", status, __LINE__ );
755 sessionKeyContext2 );
758 printf(
"cryptImportKey() failed with error code %d, line %d.\n",
765 if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
771 if( aesKeysizeOpt != AES_NONE )
773 const int sessionKeySize = ( aesKeysizeOpt == AES_128_128 || \
774 aesKeysizeOpt == AES_128_256 ) ? \
776 const int wrapKeySize = ( aesKeysizeOpt == AES_128_128 || \
777 aesKeysizeOpt == AES_256_128 ) ? \
784 printf(
"AES session key size is incorrect, line %d.\n",
792 printf(
"AES wrap key size is incorrect, line %d.\n",
804 static int testConv3DES(
void )
810 puts(
"Testing 3DES conventional key export/import via Blowfish..." );
828 printf(
"Session key context setup failed with error code %d, line "
829 "%d.\n", status, __LINE__ );
838 printf(
"Export key context setup failed with error code %d, line "
839 "%d.\n", status, __LINE__ );
844 if( !conventionalExportImport( cryptContext, sessionKeyContext1,
845 sessionKeyContext2,
FALSE, AES_NONE ) )
849 puts(
"Export/import of 3DES key via user-key-based Blowfish "
850 "conventional\n encryption succeeded." );
855 static int testConvAES(
const AES_KEYSIZE_OPT aesKeysizeOpt )
859 const char *aesKey1Name = ( aesKeysizeOpt == AES_128_128 || \
860 aesKeysizeOpt == AES_128_256 ) ? \
861 "AES-128" :
"AES-256";
862 const char *aesKey2Name = ( aesKeysizeOpt == AES_128_128 || \
863 aesKeysizeOpt == AES_256_128 ) ? \
864 "AES-128" :
"AES-256";
867 printf(
"Testing %s conventional key export/import via %s...\n",
868 aesKey1Name, aesKey2Name );
879 ( aesKeysizeOpt == AES_256_128 || aesKeysizeOpt == AES_256_256 ) )
893 printf(
"Session key context setup failed with error code %d, line "
894 "%d.\n", status, __LINE__ );
900 ( aesKeysizeOpt == AES_128_256 || aesKeysizeOpt == AES_256_256 ) )
905 printf(
"Export key context setup failed with error code %d, line "
906 "%d.\n", status, __LINE__ );
911 if( !conventionalExportImport( cryptContext, sessionKeyContext1,
912 sessionKeyContext2,
TRUE,
917 printf(
"Export/import of %s key via user-key-based %s conventional "
918 "encryption\n succeeded.\n", aesKey1Name, aesKey2Name );
925 if( !testConv3DES() )
927 if( !testConvAES( AES_128_128 ) )
929 if( !testConvAES( AES_128_256 ) )
931 if( !testConvAES( AES_256_128 ) )
933 if( !testConvAES( AES_256_256 ) )
946 C_STR userKey =
TEXT(
"This is a long user key for MAC testing" );
949 int status, length1, length2;
951 puts(
"Testing MAC key export/import..." );
970 "\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
973 userKey, userKeyLength );
978 status =
cryptExportKey( NULL, 0, &length1, cryptContext, macContext1 );
981 printf(
"cryptExportKey() failed with error code %d, line %d.\n",
985 printf(
"cryptExportKey() reports exported key object will be %d bytes "
987 if( ( buffer = malloc( length1 ) ) == NULL )
995 printf(
"cryptExportKey() failed with error code %d, line %d.\n",
1005 printf(
"cryptQueryObject() failed with error code %d, line %d.\n",
1010 printf(
"cryptQueryObject() reports object type %d, algorithm %d, mode "
1013 debugDump(
"kek_mac", buffer, length1 );
1020 printf(
"cryptCreateContext() failed with error code %d, line %d.\n",
1031 userKey, userKeyLength );
1038 printf(
"cryptImportKey() failed with error code %d, line %d.\n",
1061 printf(
"MAC operation failed with error code %d, line %d.\n",
1065 if( ( length1 != length2 ) || memcmp( mac1, mac2, length1 ) || \
1066 !memcmp( mac1,
"\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) || \
1067 !memcmp( mac2,
"\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) )
1069 puts(
"Data MAC'd with key1 != data MAC'd with key2." );
1076 printf(
"Export/import of MAC key via user-key-based triple DES "
1077 "conventional\n encryption succeeded.\n\n" );
1128 static int keygen(
const CRYPT_ALGO_TYPE cryptAlgo,
const char *algoName )
1134 printf(
"Testing %s key generation...\n", algoName );
1143 TEXT(
"Private key" ),
1148 printf(
"cryptGenerateKey() failed with error code %d, line %d.\n",
1161 BYTE hashBuffer[] =
"abcdefghijklmnopqrstuvwxyz";
1173 cryptContext, hashContext );
1183 printf(
"Sign/signature check with generated key failed "
1184 "with error code %d, line %d.\n", status,
1212 cryptContext, sessionKeyContext1 );
1215 sessionKeyContext2 );
1220 sessionKeyContext2 );
1221 printf(
"Key exchange with generated key failed with error "
1222 "code %d, line %d.\n", status, __LINE__ );
1227 if( !compareSessionKeys( sessionKeyContext1,
1228 sessionKeyContext2 ) )
1233 sessionKeyContext2 );
1240 KLUDGE_WARN(
"DH/ECDH test because of absence of DH/ECDH key exchange mechanism" );
1260 cryptContext, sessionKeyContext1 );
1263 sessionKeyContext2 );
1266 dhContext, sessionKeyContext2 );
1269 sessionKeyContext1 );
1275 sessionKeyContext2 );
1276 printf(
"Key exchange with generated key failed with error "
1277 "code %d, line %d.\n", status, __LINE__ );
1282 if( !compareSessionKeys( sessionKeyContext1,
1283 sessionKeyContext2 ) )
1288 sessionKeyContext2 );
1294 printf(
"Unexpected encryption algorithm %d found, line %d.\n",
1295 cryptAlgo, __LINE__ );
1299 printf(
"%s key generation succeeded.\n", algoName );
1326 #if !defined( UNIX_THREADS ) && !defined( WINDOWS_THREADS ) && \
1327 !defined( OS2_THREADS )
1333 BYTE hashBuffer[] =
"abcdefghijklmnopqrstuvwxyz";
1337 puts(
"Testing asynchronous key generation..." );
1349 TEXT(
"Private key" ),
1354 printf(
"cryptGenerateKeyAsync() failed with error code %d, line "
1355 "%d.\n", status, __LINE__ );
1367 printf(
"Delaying 2s to allow keygen to start..." );
1374 puts(
"Async keygen in progress." );
1381 printf(
"The async keygen has completed before the rest of the "
1382 "test code could run.\nTo fix this, either decrease "
1383 "the startup delay on line %d\nof " __FILE__
" or "
1384 "increase the size of the key being generated to slow\n"
1385 "down the generation process.\n\n", __LINE__ - 15 );
1391 printf(
"Async keygen failed with error code %d, line %d.\n", status,
1400 printf(
"cryptAsyncCancel() failed with error code %d, line %d.\n",
1404 printf(
"Cancelling async operation..." );
1422 cryptContext, hashContext );
1432 if( cancelCount <= 1 )
1434 puts(
"The async keygen completed even though the operation was "
1435 "cancelled. This was\nprobably because the CPU was fast "
1436 "enough that the keygen completed before the\ncancel could "
1441 puts(
"The async keygen completed even though the operation was "
1442 "cancelled. The\ncancel should have stopped the keygen from "
1450 puts(
"Asynchronous key generation succeeded.\n" );
1472 puts(
"Testing randomness routines. This may take a few seconds..." );
1485 puts(
"The randomness-gathering routines can't acquire enough random information to" );
1486 puts(
"allow key generation and public-key encryption to function. You will need to" );
1487 puts(
"change the randomness-polling code or reconfigure your system to allow the" );
1488 puts(
"randomness-gathering routines to function. The code to change can be found" );
1489 puts(
"in random/<osname>.c\n" );
1493 puts(
"Randomness-gathering self-test succeeded.\n" );
1504 #ifdef TEST_HIGHLEVEL
1517 puts(
"Testing CMS public-key export/import..." );
1531 printf(
"Couldn't read private key, status %d, line %d.\n", status,
1550 cryptContext, sessionKeyContext1 );
1553 printf(
"cryptExportKeyEx() failed with error code %d, line %d.\n",
1557 printf(
"cryptExportKeyEx() reports CMS exported key will be %d bytes "
1559 if( ( buffer = malloc( length ) ) == NULL )
1564 cryptContext, sessionKeyContext1 );
1567 printf(
"cryptExportKeyEx() failed with error code %d, line %d.\n",
1577 printf(
"cryptQueryObject() failed with error code %d, line %d.\n",
1582 printf(
"cryptQueryObject() reports object type %d, algorithm %d, mode "
1590 sessionKeyContext2 );
1593 printf(
"cryptImportKey() failed with error code %d, line %d.\n",
1600 if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
1606 puts(
"Export/import of CMS session key succeeded.\n" );
1613 static const CERT_DATA cmsAttributeData[] = {
1617 #ifdef USE_CMSATTR_OBSCURE
1636 static int signDataCMS(
const char *description,
1638 const BOOLEAN isCustomAttributes )
1643 BYTE *
buffer, hashBuffer[] =
"abcdefghijklmnopqrstuvwxyz";
1646 printf(
"Testing %s...\n", description );
1668 printf(
"Couldn't read private key, status %d, line %d.\n", status,
1675 signContext, hashContext, cmsAttributes );
1678 printf(
"cryptCreateSignatureEx() failed with error code %d, line "
1679 "%d.\n", status, __LINE__ );
1682 printf(
"cryptCreateSignatureEx() reports CMS signature will be %d "
1683 "bytes long\n", length );
1684 if( ( buffer = malloc( length ) ) == NULL )
1690 hashContext, cmsAttributes );
1693 printf(
"cryptCreateSignatureEx() failed with error code %d, line "
1694 "%d.\n", status, __LINE__ );
1700 ( isCustomAttributes ) ?
"cms_sigc" :
"cms_sig",
1708 printf(
"cryptCheckSignatureEx() failed with error code %d, line "
1709 "%d.\n", status, __LINE__ );
1722 printf(
"Generation and checking of %s succeeded.\n\n", description );
1730 const BYTE *extensionData =
"\x0C\x04Test";
1743 !
addCertFields( cmsAttributes, cmsAttributeData, __LINE__ ) )
1745 status = signDataCMS(
"complex CMS signature", cmsAttributes,
FALSE );
1768 status = signDataCMS(
"CMS signature with custom attributes",
1769 cmsAttributes,
TRUE );