1/* 2 * Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#include "Crypt.h" 26#include "falloc.h" 27#include <stdlib.h> 28#include <stdio.h> 29#include <time.h> 30#include "ckutilsPlatform.h" 31 32#define MIN_PASSWD_LENGTH 4 33#define MAX_PASSWD_LENGTH 20 34#define DEPTH_DEFAULT FEE_DEPTH_DEFAULT 35 36#undef BOOL 37#undef YES 38#undef NO 39#define BOOL int 40#define YES 1 41#define NO 0 42 43static unsigned char *passwdPool; 44 45static unsigned doBlobTest(unsigned minPasswdLen, 46 unsigned maxPasswdLen, 47 BOOL verbose, 48 unsigned depth); 49static void usage(char **argv); 50 51int main(int argc, char **argv) 52{ 53 BOOL seedSpec = NO; // YES ==> user specified 54 unsigned loopNum; 55 int arg; 56 char *argp; 57 58 /* 59 * User-spec'd variables 60 */ 61 unsigned minPasswordLen = MIN_PASSWD_LENGTH; 62 unsigned maxPasswordLen = MAX_PASSWD_LENGTH; 63 int seed = 0; 64 unsigned loops = 1; 65 BOOL quiet = NO; 66 BOOL verbose = NO; 67 unsigned depth = DEPTH_DEFAULT; 68 69 #if macintosh 70 argc = ccommand(&argv); 71 #endif 72 for(arg=1; arg<argc; arg++) { 73 argp = argv[arg]; 74 switch(argp[0]) { 75 case 'n': 76 minPasswordLen = atoi(&argp[2]); 77 break; 78 case 'x': 79 maxPasswordLen = atoi(&argp[2]); 80 break; 81 case 's': 82 seed = atoi(&argp[2]); 83 seedSpec = YES; 84 break; 85 case 'l': 86 loops = atoi(&argp[2]); 87 break; 88 case 'D': 89 depth = atoi(&argp[2]); 90 break; 91 case 'q': 92 quiet = YES; 93 break; 94 case 'v': 95 verbose = YES; 96 break; 97 case 'h': 98 default: 99 usage(argv); 100 } 101 } 102 if(seedSpec == NO) { 103 unsigned long tim; 104 time(&tim); 105 seed = (unsigned)tim; 106 } 107 SRAND(seed); 108 109 passwdPool = fmalloc(maxPasswordLen + 4); 110 111 printf("Starting %s: minPasswd %d maxPasswd %d seed %d depth %d\n", 112 argv[0], 113 minPasswordLen, maxPasswordLen, seed, depth); 114 115 for(loopNum=1; ; loopNum++) { 116 if(!quiet) { 117 printf("..loop %d\n", loopNum); 118 } 119 if(doBlobTest(minPasswordLen, maxPasswordLen, verbose, 120 depth)) { 121 return 1; 122 } 123 if(loops && (loopNum == loops)) { 124 break; 125 } 126 } 127 if(!quiet) { 128 printf("%s test complete\n", argv[0]); 129 } 130 return 0; 131} 132 133static void usage(char **argv) 134{ 135 printf("usage: %s [options]\n", argv[0]); 136 printf(" Options:\n"); 137 printf(" l=loops (0=forever)\n"); 138 printf(" n=minPasswordLen\n"); 139 printf(" x=maxPasswdLen\n"); 140 printf(" s=seed\n"); 141 printf(" D=depth (default=%d)\n", DEPTH_DEFAULT); 142 printf(" q(uiet)\n"); 143 printf(" v(erbose)\n"); 144 printf(" h(elp)\n"); 145 exit(1); 146} 147 148static unsigned char *genPasswd(unsigned passwdLength) 149{ 150 unsigned *ip = (unsigned *)passwdPool; 151 unsigned intCount = (passwdLength + 3) / 4; 152 int i; 153 unsigned char *rtn; 154 155 for (i=0; i<intCount; i++) { 156 *ip++ = RAND(); 157 } 158 rtn = fmalloc(passwdLength); 159 bcopy(passwdPool, rtn, passwdLength); 160 return rtn; 161} 162 163static unsigned doBlobTest(unsigned minPasswdLen, 164 unsigned maxPasswdLen, 165 BOOL verbose, 166 unsigned depth) 167{ 168 unsigned char *myPasswd = NULL; 169 unsigned myPasswdLen; 170 feePubKey myPrivate = NULL; 171 feePubKey myPrivateCopy = NULL; // from blob 172 feePubKey myPublic = NULL; // from blob from myPrivate 173 feePubKey myPublicCopy = NULL; // from blob from myPublic 174 unsigned rtn = 0; 175 feeReturn frtn; 176 unsigned char *privBlob = NULL; 177 unsigned privBlobLen; 178 unsigned char *pubBlob = NULL; 179 unsigned pubBlobLen; 180 181 for(myPasswdLen=minPasswdLen; 182 myPasswdLen<maxPasswdLen; 183 myPasswdLen++) { 184 185 if(verbose) { 186 printf("....myPasswdLen %d\n", myPasswdLen); 187 } 188 189 /* 190 * my private password 191 */ 192 myPasswd = genPasswd(myPasswdLen); 193 194 /* 195 * Fully capable Public Key object 196 */ 197 myPrivate = feePubKeyAlloc(); 198 frtn = feePubKeyInitFromPrivDataDepth(myPrivate, 199 myPasswd, 200 myPasswdLen, 201 depth, 202 1); 203 if(frtn) { 204 printf("feePubKeyInitFromPrivDataDepth: %s\n", 205 feeReturnString(frtn)); 206 rtn = 1; 207 goto out; 208 } 209 210 /* private blob */ 211 frtn = feePubKeyCreatePrivBlob(myPrivate, 212 &privBlob, 213 &privBlobLen); 214 if(frtn) { 215 printf("feePubKeyCreatePrivBlob: %s\n", 216 feeReturnString(frtn)); 217 rtn = 1; 218 goto out; 219 } 220 221 /* private key from private blob */ 222 myPrivateCopy = feePubKeyAlloc(); 223 frtn = feePubKeyInitFromPrivBlob(myPrivateCopy, 224 privBlob, 225 privBlobLen); 226 if(frtn) { 227 printf("feePubKeyInitFromKeyBlob (private): %s\n", 228 feeReturnString(frtn)); 229 rtn = 1; 230 goto out; 231 } 232 if(!feePubKeyIsPrivate(myPrivateCopy)) { 233 printf("Unexpected !feePubKeyIsPrivate!\n"); 234 rtn = 1; 235 goto out; 236 } 237 238 /* public blob from private key */ 239 frtn = feePubKeyCreatePubBlob(myPrivate, 240 &pubBlob, 241 &pubBlobLen); 242 if(frtn) { 243 printf("feePubKeyCreatePubBlob (1): %s\n", 244 feeReturnString(frtn)); 245 rtn = 1; 246 goto out; 247 } 248 249 /* public key from public blob */ 250 myPublic = feePubKeyAlloc(); 251 frtn = feePubKeyInitFromPubBlob(myPublic, 252 pubBlob, 253 pubBlobLen); 254 if(frtn) { 255 printf("feePubKeyInitFromKeyBlob (pub 1): %s\n", 256 feeReturnString(frtn)); 257 rtn = 1; 258 goto out; 259 } 260 if(feePubKeyIsPrivate(myPublic)) { 261 printf("Unexpected feePubKeyIsPrivate (1)!\n"); 262 rtn = 1; 263 goto out; 264 } 265 ffree(pubBlob); 266 pubBlob = NULL; 267 268 /* public blob from public key */ 269 frtn = feePubKeyCreatePubBlob(myPublic, 270 &pubBlob, 271 &pubBlobLen); 272 if(frtn) { 273 printf("feePubKeyCreatePubBlob (2): %s\n", 274 feeReturnString(frtn)); 275 rtn = 1; 276 goto out; 277 } 278 279 /* public key from public blob */ 280 myPublicCopy = feePubKeyAlloc(); 281 frtn = feePubKeyInitFromPubBlob(myPublicCopy, 282 pubBlob, 283 pubBlobLen); 284 if(frtn) { 285 printf("feePubKeyInitFromKeyBlob (pub 2): %s\n", 286 feeReturnString(frtn)); 287 rtn = 1; 288 goto out; 289 } 290 if(feePubKeyIsPrivate(myPublicCopy)) { 291 printf("Unexpected feePubKeyIsPrivate (2)!\n"); 292 rtn = 1; 293 goto out; 294 } 295 296 /* private blob from pub key - should fail */ 297 frtn = feePubKeyCreatePrivBlob(myPublic, 298 &pubBlob, 299 &pubBlobLen); 300 if(frtn == FR_Success) { 301 printf("Unexpected feePubKeyCreatePrivBlob success\n"); 302 rtn = 1; 303 goto out; 304 } 305 306 /* 307 * OK, we have four keys; they should all be equal (in 308 * terms of their actual public data). 309 */ 310 if(!feePubKeyIsEqual(myPrivate, myPrivateCopy)) { 311 printf("myPrivate != myPrivateCopy\n"); 312 rtn = 1; 313 goto out; 314 } 315 if(!feePubKeyIsEqual(myPrivate, myPublic)) { 316 printf("myPrivate != myPublic\n"); 317 rtn = 1; 318 goto out; 319 } 320 if(!feePubKeyIsEqual(myPrivate, myPublicCopy)) { 321 printf("myPrivate != myPublicCopy\n"); 322 rtn = 1; 323 goto out; 324 } 325 if(!feePubKeyIsEqual(myPublic, myPublicCopy)) { 326 printf("myPublic != myPublicCopy\n"); 327 rtn = 1; 328 goto out; 329 } 330 out: 331 if(myPasswd) { 332 ffree(myPasswd); 333 } 334 if(myPrivate) { 335 feePubKeyFree(myPrivate); 336 } 337 if(myPrivateCopy) { 338 feePubKeyFree(myPrivateCopy); 339 } 340 if(myPublic) { 341 feePubKeyFree(myPublic); 342 } 343 if(myPublic) { 344 feePubKeyFree(myPublicCopy); 345 } 346 if(privBlob) { 347 ffree(privBlob); 348 } 349 if(pubBlob) { 350 ffree(pubBlob); 351 } 352 if(rtn) { 353 break; 354 } 355 } 356 return rtn; 357} 358 359