1/* 2 * asymPerform.c - measure performance of RSA and FEE encrypt and decrypt 3 */ 4 5#include <stdlib.h> 6#include <stdio.h> 7#include <time.h> 8#include <Security/cssm.h> 9#include <Security/cssmapple.h> 10#include "cspwrap.h" 11#include "common.h" 12#include <string.h> 13#include <CoreFoundation/CoreFoundation.h> 14 15/* 16 * Defaults. 17 */ 18#define ENC_LOOPS_DEF 1000 19#define KEYSIZE_DEF 1024 20#define PTEXT_SIZE 20 /* e.g., a SHA1 digest */ 21 22static void usage(char **argv) 23{ 24 printf("usage: %s [options]\n", argv[0]); 25 printf(" Options:\n"); 26 printf(" a=algorithm (r=RSA; f=FEED; F=FEEDExp; default=RSA)\n"); 27 printf(" l=numLoop (default=%d)\n", ENC_LOOPS_DEF); 28 printf(" k=keySizeInBits; default=%d\n", KEYSIZE_DEF); 29 printf(" D (CSP/DL; default = bare CSP)\n"); 30 printf(" b (RSA blinding enabled)\n"); 31 printf(" v(erbose)\n"); 32 printf(" q(uiet)\n"); 33 printf(" h(elp)\n"); 34 exit(1); 35} 36 37 38int main(int argc, char **argv) 39{ 40 int arg; 41 char *argp; 42 CSSM_CSP_HANDLE cspHand; 43 unsigned i; 44 CSSM_KEY pubKey; 45 CSSM_KEY privKey; 46 CSSM_DATA_PTR ptext; // different for each loop 47 CSSM_DATA_PTR ctext; // ditto 48 CSSM_DATA_PTR rptext; // ditto 49 CSSM_RETURN crtn; 50 CFAbsoluteTime start, end; 51 CSSM_CC_HANDLE ccHand; 52 unsigned ctextSize; 53 CSSM_ACCESS_CREDENTIALS creds; 54 CSSM_SIZE processed; 55 CSSM_DATA remData; 56 57 /* 58 * User-spec'd params 59 */ 60 uint32 keySizeInBits = KEYSIZE_DEF; 61 unsigned encLoops = ENC_LOOPS_DEF; 62 CSSM_BOOL verbose = CSSM_FALSE; 63 CSSM_BOOL quiet = CSSM_FALSE; 64 CSSM_BOOL bareCsp = CSSM_TRUE; 65 CSSM_BOOL rsaBlinding = CSSM_FALSE; 66 CSSM_ALGORITHMS keyAlg = CSSM_ALGID_RSA; 67 CSSM_ALGORITHMS encrAlg = CSSM_ALGID_RSA; 68 CSSM_PADDING padding = CSSM_PADDING_PKCS1; 69 70 for(arg=1; arg<argc; arg++) { 71 argp = argv[arg]; 72 switch(argp[0]) { 73 case 'a': 74 if(argp[1] != '=') { 75 usage(argv); 76 } 77 switch(argp[2]) { 78 case 'r': 79 encrAlg = keyAlg = CSSM_ALGID_RSA; 80 break; 81 case 'f': 82 encrAlg = CSSM_ALGID_FEED; 83 keyAlg = CSSM_ALGID_FEE; 84 padding = CSSM_PADDING_NONE; 85 break; 86 case 'F': 87 encrAlg = CSSM_ALGID_FEEDEXP; 88 keyAlg = CSSM_ALGID_FEE; 89 padding = CSSM_PADDING_NONE; 90 break; 91 default: 92 usage(argv); 93 } 94 break; 95 case 'l': 96 encLoops = atoi(&argp[2]); 97 break; 98 case 'k': 99 keySizeInBits = atoi(&argp[2]); 100 break; 101 case 'v': 102 verbose = CSSM_TRUE; 103 break; 104 case 'D': 105 bareCsp = CSSM_FALSE; 106 break; 107 case 'b': 108 rsaBlinding = CSSM_TRUE; 109 break; 110 case 'q': 111 quiet = CSSM_TRUE; 112 break; 113 case 'h': 114 default: 115 usage(argv); 116 } 117 } 118 119 cspHand = cspDlDbStartup(bareCsp, NULL); 120 if(cspHand == 0) { 121 exit(1); 122 } 123 124 /* malloc encLoops ptext and ctext structs and the data they contain */ 125 ptext = (CSSM_DATA_PTR)CSSM_MALLOC(encLoops * sizeof(CSSM_DATA)); 126 ctext = (CSSM_DATA_PTR)CSSM_MALLOC(encLoops * sizeof(CSSM_DATA)); 127 rptext = (CSSM_DATA_PTR)CSSM_MALLOC(encLoops * sizeof(CSSM_DATA)); 128 memset(ptext, 0, encLoops * sizeof(CSSM_DATA)); 129 memset(ctext, 0, encLoops * sizeof(CSSM_DATA)); 130 memset(rptext, 0, encLoops * sizeof(CSSM_DATA)); 131 ctextSize = (keySizeInBits + 7) / 8; 132 if(keyAlg != CSSM_ALGID_RSA) { 133 ctextSize *= 8; 134 } 135 for(i=0; i<encLoops; i++) { 136 appSetupCssmData(&ptext[i], PTEXT_SIZE); 137 appSetupCssmData(&ctext[i], ctextSize); 138 } 139 140 /* generate random "digests" */ 141 for(i=0; i<encLoops; i++) { 142 simpleGenData(&ptext[i], PTEXT_SIZE, PTEXT_SIZE); 143 } 144 145 printf("Generating keys....\n"); 146 crtn = cspGenKeyPair(cspHand, 147 keyAlg, 148 "foo", 149 3, 150 keySizeInBits, 151 &pubKey, 152 CSSM_TRUE, // reference key for speed 153 CSSM_KEYUSE_ANY, 154 CSSM_KEYBLOB_RAW_FORMAT_NONE, 155 &privKey, 156 CSSM_TRUE, 157 CSSM_KEYUSE_ANY, 158 CSSM_KEYBLOB_RAW_FORMAT_NONE, 159 CSSM_FALSE); // genSeed not used 160 if(crtn) { 161 return testError(quiet); 162 } 163 164 printf("Encrypting....\n"); 165 166 /* set up a reusable crypt context */ 167 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); 168 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand, 169 encrAlg, 170 &creds, 171 (encrAlg == CSSM_ALGID_FEED) ? &privKey : &pubKey, 172 padding, 173 &ccHand); 174 if(crtn) { 175 printError("CSSM_CSP_CreateAsymmetricContext (1)", crtn); 176 return 1; 177 } 178 if(encrAlg == CSSM_ALGID_FEED) { 179 AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PUBLIC_KEY, 180 sizeof(CSSM_KEY), CAT_Ptr, &pubKey, 0); 181 } 182 183 /* go - critical encrypt loop */ 184 start = CFAbsoluteTimeGetCurrent(); 185 for(i=0; i<encLoops; i++) { 186 crtn = CSSM_EncryptData(ccHand, 187 &ptext[i], 188 1, 189 &ctext[i], 190 1, 191 &processed, 192 &remData); 193 ctext[i].Length = processed; 194 if(crtn) { 195 printError("CSSM_EncryptData", crtn); 196 return 1; 197 } 198 } 199 end = CFAbsoluteTimeGetCurrent(); 200 printf("%d encr ops in %f seconds, %f ms/op\n", encLoops, end-start, 201 ((end - start) * 1000.0) / encLoops); 202 203 CSSM_DeleteContext(ccHand); 204 205 /* set up a reusable encryption context */ 206 crtn = CSSM_CSP_CreateAsymmetricContext(cspHand, 207 encrAlg, 208 &creds, 209 &privKey, 210 padding, 211 &ccHand); 212 if(crtn) { 213 printError("CSSM_CSP_CreateAsymmetricContext (2)", crtn); 214 return 1; 215 } 216 if(rsaBlinding) { 217 CSSM_CONTEXT_ATTRIBUTE newAttr; 218 newAttr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; 219 newAttr.AttributeLength = sizeof(uint32); 220 newAttr.Attribute.Uint32 = 1; 221 crtn = CSSM_UpdateContextAttributes(ccHand, 1, &newAttr); 222 if(crtn) { 223 printError("CSSM_UpdateContextAttributes", crtn); 224 return crtn; 225 } 226 } 227 if(encrAlg == CSSM_ALGID_FEED) { 228 AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PUBLIC_KEY, 229 sizeof(CSSM_KEY), CAT_Ptr, &pubKey, 0); 230 } 231 232 /* go - critical decrypt loop */ 233 start = CFAbsoluteTimeGetCurrent(); 234 for(i=0; i<encLoops; i++) { 235 crtn = CSSM_DecryptData(ccHand, 236 &ctext[i], 237 1, 238 &rptext[i], 239 1, 240 &processed, 241 &remData); 242 if(crtn) { 243 printError("CSSM_DecryptData", crtn); 244 return 1; 245 } 246 } 247 end = CFAbsoluteTimeGetCurrent(); 248 printf("%d decr ops in %f seconds, %f ms/op\n", encLoops, end-start, 249 ((end - start) * 1000.0) / encLoops); 250 CSSM_DeleteContext(ccHand); 251 252 cspFreeKey(cspHand, &privKey); 253 cspFreeKey(cspHand, &pubKey); 254 for(i=0; i<encLoops; i++) { 255 appFreeCssmData(&ptext[i], CSSM_FALSE); 256 appFreeCssmData(&ctext[i], CSSM_FALSE); 257 appFreeCssmData(&rptext[i], CSSM_FALSE); 258 } 259 CSSM_FREE(ptext); 260 CSSM_FREE(ctext); 261 CSSM_FREE(rptext); 262 cspShutdown(cspHand, bareCsp); 263 return 0; 264} 265 266 267