2 * CSP symmetric encryption performance measurement tool
3 * Based on Michael Brouwer's cryptoPerformance.cpp
6 #include <CoreFoundation/CoreFoundation.h>
7 #include <security_cdsa_utilities/cssmdata.h>
8 #include <security_cdsa_utilities/cssmerrors.h>
9 #include <security_cdsa_client/genkey.h>
10 #include <security_cdsa_client/wrapkey.h>
21 #define ALG_DEFAULT CSSM_ALGID_AES
22 #define ALG_STR_DEFAULT "AES"
23 #define CHAIN_DEFAULT CSSM_TRUE
24 #define KEY_SIZE_DEFAULT 128
26 #define BEGIN_FUNCTION try {
28 #define END_FUNCTION } \
29 catch (const CssmError &e) \
31 cssmPerror(__PRETTY_FUNCTION__, e.error); \
35 fprintf(stderr, "%s: failed\n", __PRETTY_FUNCTION__); \
38 static void usage(char **argv)
40 printf("usage: %s iterations bufsize [options]\n", argv
[0]);
41 printf(" Options:\n");
42 printf(" a=algorithm (s=ASC; d=DES; 3=3DES; 2=RC2; 4=RC4; 5=RC5;\n");
43 printf(" a=AES; b=Blowfish; c=CAST; n=NULL; default=AES)\n");
44 printf(" k=keySizeInBits\n");
45 printf(" b=blockSizeInBits\n");
46 printf(" e (ECB mode; default is CBC)\n");
47 printf(" i (re-set IV in each loop)\n");
48 printf(" v(erbose)\n");
54 cdsaSetupContexts(int iterations
,
55 auto_ptr
<Security::CssmClient::Encrypt
> &encrypt
,
56 auto_ptr
<Security::CssmClient::Decrypt
> &decrypt
,
57 CSSM_ALGORITHMS keyAlg
,
58 CSSM_ALGORITHMS encrAlg
,
59 CSSM_ENCRYPT_MODE encrMode
,
61 uint32 blockSizeInBits
) // optional
64 Security::CssmClient::CSP
csp(gGuidAppleCSP
);
65 //CssmData keyData((uint8 *)"1234567812345678", 16);
66 Security::CssmClient::GenerateKey
keyGenerator(csp
, keyAlg
, keySizeInBits
);
67 Security::CssmClient::Key key
= keyGenerator(Security::CssmClient::KeySpec(
68 CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
,
69 CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_EXTRACTABLE
));
70 for (int ix
=0; ix
< iterations
; ++ix
)
72 encrypt
.reset(new Security::CssmClient::Encrypt(csp
, encrAlg
));
73 encrypt
->mode(encrMode
);
76 encrypt
->add(CSSM_ATTRIBUTE_BLOCK_SIZE
, blockSizeInBits
/ 8);
78 //encrypt->activate();
80 decrypt
.reset(new Security::CssmClient::Decrypt(csp
, encrAlg
));
81 decrypt
->mode(encrMode
);
84 decrypt
->add(CSSM_ATTRIBUTE_BLOCK_SIZE
, blockSizeInBits
/ 8);
86 //decrypt->activate();
92 cdsaEncrypt(int iterations
, Security::CssmClient::Encrypt
&encrypt
,
93 uint8
*inBuf
, uint32 bufLen
, uint8
*outBuf
, bool useIv
, uint32 blockSizeBytes
,
97 CssmData
iv((uint8
*)"12345678123456781234567812345678", blockSizeBytes
);
98 CssmData
inData(inBuf
, bufLen
);
99 CssmData
outData(outBuf
, bufLen
);
100 CssmData
nullData(reinterpret_cast<uint8
*>(NULL
) + 1, 0);
102 encrypt
.initVector(iv
);
104 if(useIv
&& resetIv
) {
105 for (int ix
=0; ix
< iterations
; ++ix
)
107 encrypt
.initVector(iv
);
108 encrypt
.encrypt(inData
, outData
, nullData
);
112 for (int ix
=0; ix
< iterations
; ++ix
)
114 encrypt
.encrypt(inData
, outData
, nullData
);
121 cdsaDecrypt(int iterations
, Security::CssmClient::Decrypt
&decrypt
,
122 uint8
*inBuf
, uint32 bufLen
, uint8
*outBuf
, bool useIv
, uint32 blockSizeBytes
,
126 CssmData
iv((uint8
*)"12345678123456781234567812345678", blockSizeBytes
);
127 CssmData
inData(inBuf
, bufLen
);
128 CssmData
outData(outBuf
, bufLen
);
129 CssmData
nullData(reinterpret_cast<uint8
*>(NULL
) + 1, 0);
131 decrypt
.initVector(iv
);
133 if(useIv
&& resetIv
) {
134 for (int ix
=0; ix
< iterations
; ++ix
)
136 decrypt
.initVector(iv
);
137 decrypt
.decrypt(inData
, outData
, nullData
);
141 for (int ix
=0; ix
< iterations
; ++ix
)
143 decrypt
.decrypt(inData
, outData
, nullData
);
149 int main(int argc
, char **argv
)
153 CSSM_ENCRYPT_MODE mode
;
154 uint32 blockSizeBytes
= 8;
159 CSSM_BOOL chainEnable
= CHAIN_DEFAULT
;
160 uint32 keySizeInBits
= KEY_SIZE_DEFAULT
;
161 uint32 blockSizeInBits
= 0;
162 const char *algStr
= ALG_STR_DEFAULT
;
163 uint32 keyAlg
= ALG_DEFAULT
; // CSSM_ALGID_xxx of the key
164 uint32 encrAlg
= ALG_DEFAULT
; // CSSM_ALGID_xxx for encrypt
167 CSSM_BOOL resetIv
= CSSM_FALSE
;
168 CSSM_BOOL verbose
= false;
173 iterations
= atoi(argv
[1]);
174 bufSize
= atoi(argv
[2]);
175 for(arg
=3; arg
<argc
; arg
++) {
184 encrAlg
= keyAlg
= CSSM_ALGID_ASC
;
188 encrAlg
= keyAlg
= CSSM_ALGID_DES
;
193 keyAlg
= CSSM_ALGID_3DES_3KEY
;
194 encrAlg
= CSSM_ALGID_3DES_3KEY_EDE
;
196 keySizeInBits
= 64 * 3;
199 encrAlg
= keyAlg
= CSSM_ALGID_RC2
;
203 encrAlg
= keyAlg
= CSSM_ALGID_RC4
;
205 /* not a block cipher */
206 chainEnable
= CSSM_FALSE
;
209 encrAlg
= keyAlg
= CSSM_ALGID_RC5
;
213 encrAlg
= keyAlg
= CSSM_ALGID_AES
;
217 encrAlg
= keyAlg
= CSSM_ALGID_BLOWFISH
;
221 encrAlg
= keyAlg
= CSSM_ALGID_CAST
;
225 encrAlg
= keyAlg
= CSSM_ALGID_NONE
;
233 keySizeInBits
= atoi(&argp
[2]);
236 blockSizeInBits
= atoi(&argp
[2]);
239 chainEnable
= CSSM_FALSE
;
254 chainEnable
= CSSM_FALSE
;
255 mode
= CSSM_ALGMODE_NONE
;
256 if((iterations
& 1) == 0) {
257 printf("***WARNING: an even number of iterations with RC4 results in\n"
258 " identical plaintext and ciphertext!\n");
262 case CSSM_ALGID_NONE
:
263 blockSizeBytes
= blockSizeInBits
? (blockSizeInBits
/ 8) : 16;
269 mode
= CSSM_ALGMODE_CBC_IV8
;
272 mode
= CSSM_ALGMODE_ECB
;
275 if(blockSizeInBits
) {
276 printf("Algorithm: %s keySize: %u blockSize: %u mode: %s"
277 " iterations: %d bufSize %d\n",
278 algStr
, (unsigned)keySizeInBits
, (unsigned)blockSizeInBits
,
279 chainEnable
? "CBC" : "ECB",
280 iterations
, bufSize
);
283 printf("Algorithm: %s keySize: %u mode: %s iterations: %d "
285 algStr
, (unsigned)keySizeInBits
, chainEnable
? "CBC" : "ECB",
286 iterations
, bufSize
);
288 CFAbsoluteTime start
, end
;
289 auto_array
<uint8
> buffer(bufSize
), plain(bufSize
);
290 auto_ptr
<Security::CssmClient::Encrypt
> encrypt(NULL
);
291 auto_ptr
<Security::CssmClient::Decrypt
> decrypt(NULL
);
293 uint8
*bp
= buffer
.get();
294 for(int ix
=0; ix
<bufSize
; ix
++) {
297 memcpy(plain
.get(), buffer
.get(), bufSize
);
300 printf("%d * cdsaSetupContexts", iterations
);
303 start
= CFAbsoluteTimeGetCurrent();
304 cdsaSetupContexts(iterations
, encrypt
, decrypt
,
305 keyAlg
, encrAlg
, mode
, keySizeInBits
, blockSizeInBits
);
306 end
= CFAbsoluteTimeGetCurrent();
308 printf(" took: %gs\n", end
- start
);
311 printf(" %d * cdsaEncrypt %d bytes", iterations
, bufSize
);
313 start
= CFAbsoluteTimeGetCurrent();
314 cdsaEncrypt(iterations
, *encrypt
.get(), buffer
.get(), bufSize
, buffer
.get(),
315 chainEnable
, blockSizeBytes
, resetIv
);
316 end
= CFAbsoluteTimeGetCurrent();
317 printf(" took: %gs %.1f Kbytes/s\n", end
- start
,
318 (iterations
* bufSize
) / (end
- start
) / 1024.0);
320 if (!memcmp(buffer
.get(), plain
.get(), bufSize
))
321 printf("*** ciphertext matches plaintext ***\n");
323 printf(" %d * cdsaDecrypt %d bytes", iterations
, bufSize
);
325 start
= CFAbsoluteTimeGetCurrent();
326 cdsaDecrypt(iterations
, *decrypt
.get(), buffer
.get(), bufSize
, buffer
.get(),
327 chainEnable
, blockSizeBytes
, resetIv
);
328 end
= CFAbsoluteTimeGetCurrent();
329 printf(" took: %gs %.1f Kbytes/s\n", end
- start
,
330 (iterations
* bufSize
) / (end
- start
) / 1024.0);
332 if (memcmp(buffer
.get(), plain
.get(), bufSize
))
333 printf("*** plaintext not recovered correctly ***\n");
336 printf("plaintext recovered\n");