1/* 2 * rawRsaSig.c - Test compatiblity of CSSM_ALGID_{SHA1,MD5}WithRSA and 3 * manual digest followed by raw RSA sign. 4 */ 5 6#include <stdlib.h> 7#include <stdio.h> 8#include <time.h> 9#include <Security/cssm.h> 10#include <Security/cssmapple.h> 11#include "cspwrap.h" 12#include "common.h" 13#include "bsafeUtils.h" 14#include <string.h> 15 16/* 17 * Defaults. 18 */ 19#define OLOOPS_DEF 10 /* outer loops, one key pair per loop */ 20#define ILOOPS_DEF 10 /* sig loops */ 21#define MAX_TEXT_SIZE 1024 22 23#define LOOP_NOTIFY 20 24#define DO_MULTI_UPDATE CSSM_TRUE 25 26static void usage(char **argv) 27{ 28 printf("usage: %s [options]\n", argv[0]); 29 printf(" Options:\n"); 30 printf(" a=alg (r=RSA, d=DSA; default=RSA)\n"); 31 printf(" l=outerloops (default=%d; 0=forever)\n", OLOOPS_DEF); 32 printf(" i=innerLoops (default=%d)\n", ILOOPS_DEF); 33 printf(" k=keySizeInBits; default is random\n"); 34 printf(" p=pauseInterval (default=0, no pause)\n"); 35 printf(" D (CSP/DL; default = bare CSP)\n"); 36 printf(" v(erbose)\n"); 37 printf(" q(uiet)\n"); 38 printf(" h(elp)\n"); 39 exit(1); 40} 41 42int main(int argc, char **argv) 43{ 44 int arg; 45 char *argp; 46 unsigned oloop; 47 unsigned iloop; 48 CSSM_DATA ptext = {0, NULL}; 49 CSSM_CSP_HANDLE cspHand; 50 int i; 51 int rtn = 0; 52 uint32 keySizeInBits = 0; 53 CSSM_KEY pubKey; 54 CSSM_KEY privKey; 55 CSSM_DATA sig = {0, NULL}; 56 CSSM_DATA digest = {0, NULL}; 57 CSSM_RETURN crtn; 58 const char *digestStr; 59 60 /* 61 * User-spec'd params 62 */ 63 CSSM_BOOL keySizeSpec = CSSM_FALSE; 64 unsigned oloops = OLOOPS_DEF; 65 unsigned iloops = ILOOPS_DEF; 66 CSSM_BOOL verbose = CSSM_FALSE; 67 CSSM_BOOL quiet = CSSM_FALSE; 68 unsigned pauseInterval = 0; 69 CSSM_BOOL bareCsp = CSSM_TRUE; 70 CSSM_ALGORITHMS rawSigAlg = CSSM_ALGID_RSA; 71 72 for(arg=1; arg<argc; arg++) { 73 argp = argv[arg]; 74 switch(argp[0]) { 75 case 'a': 76 switch(argp[2]) { 77 case 'r': 78 rawSigAlg = CSSM_ALGID_RSA; 79 break; 80 case 'd': 81 rawSigAlg = CSSM_ALGID_DSA; 82 break; 83 default: 84 usage(argv); 85 } 86 break; 87 case 'l': 88 oloops = atoi(&argp[2]); 89 break; 90 case 'i': 91 iloops = atoi(&argp[2]); 92 break; 93 case 'k': 94 keySizeInBits = atoi(&argp[2]); 95 keySizeSpec = CSSM_TRUE; 96 break; 97 case 'v': 98 verbose = CSSM_TRUE; 99 break; 100 case 'D': 101 bareCsp = CSSM_FALSE; 102 break; 103 case 'q': 104 quiet = CSSM_TRUE; 105 break; 106 case 'p': 107 pauseInterval = atoi(&argp[2]);; 108 break; 109 case 'h': 110 default: 111 usage(argv); 112 } 113 } 114 115 ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE); 116 if(ptext.Data == NULL) { 117 printf("Insufficient heap space\n"); 118 exit(1); 119 } 120 /* ptext length set in inner test loop */ 121 122 printf("Starting rawRsaSig; args: "); 123 for(i=1; i<argc; i++) { 124 printf("%s ", argv[i]); 125 } 126 printf("\n"); 127 cspHand = cspDlDbStartup(bareCsp, NULL); 128 if(cspHand == 0) { 129 exit(1); 130 } 131 if(pauseInterval) { 132 fpurge(stdin); 133 printf("Top of test; hit CR to proceed: "); 134 getchar(); 135 } 136 for(oloop=0; ; oloop++) { 137 138 /* key size? */ 139 if(!keySizeSpec) { 140 /* random key size */ 141 keySizeInBits = randKeySizeBits(rawSigAlg, OT_Sign); 142 } 143 144 if(!quiet) { 145 if(verbose || ((oloop % LOOP_NOTIFY) == 0)) { 146 printf("...oloop %d keySize %u\n", oloop, (unsigned)keySizeInBits); 147 } 148 } 149 150 /* generate a key pair */ 151 crtn = cspGenKeyPair(cspHand, 152 rawSigAlg, 153 "foo", 154 3, 155 keySizeInBits, 156 &pubKey, 157 CSSM_TRUE, // all keys ref for speed 158 CSSM_KEYUSE_VERIFY, 159 CSSM_KEYBLOB_RAW_FORMAT_NONE, 160 &privKey, 161 CSSM_TRUE, 162 CSSM_KEYUSE_SIGN, 163 CSSM_KEYBLOB_RAW_FORMAT_NONE, 164 CSSM_FALSE); // genSeed not used 165 if(crtn) { 166 return testError(quiet); 167 } 168 169 for(iloop=0; iloop<iloops; iloop++) { 170 171 CSSM_ALGORITHMS sigAlg; 172 CSSM_ALGORITHMS digestAlg; 173 CSSM_CC_HANDLE sigHand; 174 175 /* alternate digest algs for RSA */ 176 if(rawSigAlg == CSSM_ALGID_RSA) { 177 if(iloop & 1) { 178 sigAlg = CSSM_ALGID_SHA1WithRSA; 179 digestAlg = CSSM_ALGID_SHA1; 180 digestStr = "SHA1"; 181 } 182 else { 183 sigAlg = CSSM_ALGID_MD5WithRSA; 184 digestAlg = CSSM_ALGID_MD5; 185 digestStr = "MD5 "; 186 } 187 } 188 else { 189 sigAlg = CSSM_ALGID_SHA1WithDSA; 190 digestAlg = CSSM_ALGID_SHA1; 191 digestStr = "SHA1"; 192 } 193 194 /* new plaintext each inner loop */ 195 simpleGenData(&ptext, 1, MAX_TEXT_SIZE); 196 if(!quiet) { 197 if(verbose || ((iloop % LOOP_NOTIFY) == 0)) { 198 printf(" ...iloop %d digest %s text size %lu\n", 199 iloop, digestStr, ptext.Length); 200 } 201 } 202 203 /*** phase 1 ***/ 204 205 /* digest+sign */ 206 crtn = cspStagedSign(cspHand, 207 sigAlg, 208 &privKey, 209 &ptext, 210 DO_MULTI_UPDATE, // multiUpdates 211 &sig); 212 if(crtn && testError(quiet)) { 213 goto abort; 214 } 215 216 /* digest */ 217 crtn = cspStagedDigest(cspHand, 218 digestAlg, 219 CSSM_FALSE, // mallocDigest 220 DO_MULTI_UPDATE, // multiUpdates 221 &ptext, 222 &digest); 223 if(crtn && testError(quiet)) { 224 goto abort; 225 } 226 227 /* raw RSA/DSA verify */ 228 crtn = CSSM_CSP_CreateSignatureContext(cspHand, 229 rawSigAlg, 230 NULL, // passPhrase 231 &pubKey, 232 &sigHand); 233 if(crtn) { 234 printError("CSSM_CSP_CreateSignatureContext (1)", crtn); 235 return crtn; 236 } 237 crtn = CSSM_VerifyData(sigHand, 238 &digest, 239 1, 240 digestAlg, 241 &sig); 242 if(crtn) { 243 printError("CSSM_VerifyData(raw RSA)", crtn); 244 if(testError(quiet)) { 245 goto abort; 246 } 247 } 248 249 /* free resources - reuse the digest for raw sign */ 250 appFreeCssmData(&sig, CSSM_FALSE); 251 CSSM_DeleteContext(sigHand); 252 253 /*** phase 2 ***/ 254 255 /* raw RSA/DSA sign */ 256 crtn = CSSM_CSP_CreateSignatureContext(cspHand, 257 rawSigAlg, 258 NULL, // passPhrase 259 &privKey, 260 &sigHand); 261 if(crtn) { 262 printError("CSSM_CSP_CreateSignatureContext (1)", crtn); 263 return crtn; 264 } 265 crtn = CSSM_SignData(sigHand, 266 &digest, 267 1, 268 digestAlg, 269 &sig); 270 if(crtn) { 271 printError("CSSM_SignData(raw RSA)", crtn); 272 if(testError(quiet)) { 273 goto abort; 274 } 275 } 276 277 /* all-in-one verify */ 278 crtn = cspStagedSigVerify(cspHand, 279 sigAlg, 280 &pubKey, 281 &ptext, 282 &sig, 283 DO_MULTI_UPDATE, // multiUpdates 284 CSSM_OK); 285 if(crtn && testError(quiet)) { 286 goto abort; 287 } 288 289 /* clean up */ 290 appFreeCssmData(&sig, CSSM_FALSE); 291 appFreeCssmData(&digest, CSSM_FALSE); 292 CSSM_DeleteContext(sigHand); 293 } /* end of inner loop */ 294 295 /* free keys */ 296 cspFreeKey(cspHand, &pubKey); 297 cspFreeKey(cspHand, &privKey); 298 299 if(oloops && (oloop == oloops)) { 300 break; 301 } 302 if(pauseInterval && ((oloop % pauseInterval) == 0)) { 303 fpurge(stdin); 304 printf("hit CR to proceed: "); 305 getchar(); 306 } 307 } 308 309abort: 310 cspShutdown(cspHand, bareCsp); 311 if(pauseInterval) { 312 fpurge(stdin); 313 printf("ModuleDetach/Unload complete; hit CR to exit: "); 314 getchar(); 315 } 316 if((rtn == 0) && !quiet) { 317 printf("%s test complete\n", argv[0]); 318 } 319 CSSM_FREE(ptext.Data); 320 return rtn; 321} 322 323 324