]>
git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/ccHmacClone/ccHmacClone.cpp
2 * ccHmacClone - test CommonCrypto's clone context for HMAC.
4 * Written 3/30/2006 by Doug Mitchell.
12 #include <CommonCrypto/CommonHMAC.h>
19 #define MIN_DATA_SIZE 8
20 #define MAX_DATA_SIZE 10000 /* bytes */
21 #define MIN_KEY_SIZE 1
22 #define MAX_KEY_SIZE 256 /* bytes */
23 #define LOOP_NOTIFY 20
26 * Enumerate algs our own way to allow iteration.
36 #define ALG_FIRST ALG_MD5
37 #define ALG_LAST ALG_SHA512
41 #define logSize(s) printf s
46 static void usage(char **argv
)
48 printf("usage: %s [options]\n", argv
[0]);
49 printf(" Options:\n");
50 printf(" a=algorithm (5=MD5; s=SHA1; 4=SHA224; 2=SHA256; 3=SHA384; 1=SHA512; default=all)\n");
51 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF
);
52 printf(" k=keySizeInBytes\n");
53 printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE
);
54 printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE
);
55 printf(" p=pauseInterval (default=0, no pause)\n");
56 printf(" s (all ops single-shot, not staged)\n");
57 printf(" S (all ops staged)\n");
58 printf(" z (keys and plaintext all zeroes)\n");
59 printf(" v(erbose)\n");
66 * Given an initialized CCHmacContext, feed it some data and get the result.
71 const unsigned char *ptext
,
76 size_t thisMoveIn
; /* input to CCryptUpdate() */
79 thisMoveIn
= genRand(1, ptextLen
);
82 thisMoveIn
= ptextLen
;
84 logSize(("###ptext segment (1) len %lu\n", (unsigned long)thisMoveIn
));
85 CCHmacUpdate(ctx
, ptext
, thisMoveIn
);
87 ptextLen
-= thisMoveIn
;
89 CCHmacFinal(ctx
, dataOut
);
93 #define MAX_HMAC_SIZE CC_SHA512_DIGEST_LENGTH
95 static int doTest(const uint8_t *ptext
,
97 CCHmacAlgorithm hmacAlg
,
98 uint32 keySizeInBytes
,
104 uint8_t keyBytes
[MAX_KEY_SIZE
];
105 uint8_t hmacOrig
[MAX_HMAC_SIZE
];
106 uint8_t hmacClone
[MAX_HMAC_SIZE
];
108 CCHmacContext ctxOrig
;
109 CCHmacContext ctxClone
;
110 unsigned die
; /* 0..3 indicates when to clone */
111 unsigned loopNum
= 0;
113 bool didClone
= false;
117 hmacLen
= CC_SHA1_DIGEST_LENGTH
;
120 hmacLen
= CC_MD5_DIGEST_LENGTH
;
122 case kCCHmacAlgSHA224
:
123 hmacLen
= CC_SHA224_DIGEST_LENGTH
;
125 case kCCHmacAlgSHA256
:
126 hmacLen
= CC_SHA256_DIGEST_LENGTH
;
128 case kCCHmacAlgSHA384
:
129 hmacLen
= CC_SHA384_DIGEST_LENGTH
;
131 case kCCHmacAlgSHA512
:
132 hmacLen
= CC_SHA512_DIGEST_LENGTH
;
135 printf("***BRRRZAP!\n");
140 appGetRandomBytes(keyBytes
, keySizeInBytes
);
142 /* cook up first context */
143 CCHmacInit(&ctxOrig
, hmacAlg
, keyBytes
, keySizeInBytes
);
149 * In this loop we do updates to the ctxOrig up until we
150 * clone it, then we use hmacRun to finish both of them.
153 if((die
== loopNum
) || !stagedOrig
) {
154 /* make the clone now */
156 printf(" ...cloning at loop %u\n", loopNum
);
161 /* do all of the clone's updates and final here */
162 hmacRun(&ctxClone
, stagedClone
, ptext
, ptextLen
, hmacClone
);
164 /* now do all remaining updates and final for original */
165 hmacRun(&ctxOrig
, stagedOrig
, ptext
, ptextLen
, hmacOrig
);
167 /* we're all done, time to check the HMAC values */
171 /* feed some data into cryptorOrig */
174 thisMove
= genRand(1, ptextLen
);
179 logSize(("###ptext segment (2) len %lu\n", (unsigned long)thisMove
));
180 CCHmacUpdate(&ctxOrig
, ptext
, thisMove
);
182 ptextLen
-= thisMove
;
187 * It's possible to get here without cloning or doing any finals,
188 * if we ran thru multiple updates and finished ptextLen for cryptorOrig
189 * before we hit the cloning spot.
193 printf("...ctxOrig finished before we cloned; skipping test\n");
197 if(memcmp(hmacOrig
, hmacClone
, hmacLen
)) {
198 printf("***data miscompare\n");
199 rtn
= testError(quiet
);
204 bool isBitSet(unsigned bit
, unsigned word
)
207 printf("We don't have that many bits\n");
210 unsigned mask
= 1 << bit
;
211 return (word
& mask
) ? true : false;
214 int main(int argc
, char **argv
)
224 CCHmacAlgorithm hmacAlg
;
226 int currAlg
; // ALG_xxx
227 uint32 keySizeInBytes
;
233 bool keySizeSpec
= false; // false: use rand key size
234 HmacAlg minAlg
= ALG_FIRST
;
235 HmacAlg maxAlg
= ALG_LAST
;
236 unsigned loops
= LOOPS_DEF
;
237 bool verbose
= false;
238 size_t minPtextSize
= MIN_DATA_SIZE
;
239 size_t maxPtextSize
= MAX_DATA_SIZE
;
241 unsigned pauseInterval
= 0;
242 bool stagedSpec
= false; // true means caller fixed stagedOrig and stagedClone
244 for(arg
=1; arg
<argc
; arg
++) {
253 minAlg
= maxAlg
= ALG_MD5
;
256 minAlg
= maxAlg
= ALG_SHA1
;
259 minAlg
= maxAlg
= ALG_SHA224
;
262 minAlg
= maxAlg
= ALG_SHA256
;
265 minAlg
= maxAlg
= ALG_SHA384
;
268 minAlg
= maxAlg
= ALG_SHA512
;
275 loops
= atoi(&argp
[2]);
278 minPtextSize
= atoi(&argp
[2]);
281 maxPtextSize
= atoi(&argp
[2]);
284 keySizeInBytes
= atoi(&argp
[2]);
294 pauseInterval
= atoi(&argp
[2]);;
297 stagedOrig
= stagedClone
= false;
301 stagedOrig
= stagedClone
= true;
309 ptext
= (uint8
*)malloc(maxPtextSize
);
311 printf("Insufficient heap space\n");
314 /* ptext length set in test loop */
316 printf("Starting ccHmacClone; args: ");
317 for(i
=1; i
<argc
; i
++) {
318 printf("%s ", argv
[i
]);
324 printf("Top of test; hit CR to proceed: ");
328 for(currAlg
=minAlg
; currAlg
<=maxAlg
; currAlg
++) {
329 /* when zero, set size randomly or per user setting */
332 hmacAlg
= kCCHmacAlgMD5
;
336 hmacAlg
= kCCHmacAlgSHA1
;
340 hmacAlg
= kCCHmacAlgSHA224
;
341 algStr
= "HMACSHA224";
344 hmacAlg
= kCCHmacAlgSHA256
;
345 algStr
= "HMACSHA256";
348 hmacAlg
= kCCHmacAlgSHA384
;
349 algStr
= "HMACSHA384";
352 hmacAlg
= kCCHmacAlgSHA512
;
353 algStr
= "HMACSHA512";
356 printf("***BRRZAP!\n");
359 if(!quiet
|| verbose
) {
360 printf("Testing alg %s\n", algStr
);
362 for(loop
=1; ; loop
++) {
363 ptextLen
= genRand(minPtextSize
, maxPtextSize
);
364 appGetRandomBytes(ptext
, ptextLen
);
366 keySizeInBytes
= genRand(MIN_KEY_SIZE
, MAX_KEY_SIZE
);
369 /* per-loop settings */
371 stagedOrig
= isBitSet(1, loop
);
372 stagedClone
= isBitSet(2, loop
);
376 if(verbose
|| ((loop
% LOOP_NOTIFY
) == 0)) {
377 printf("..loop %d ptextLen %4lu keySize %3lu stagedOrig=%d "
379 loop
, (unsigned long)ptextLen
, (unsigned long)keySizeInBytes
,
380 (int)stagedOrig
, (int)stagedClone
);
384 if(doTest(ptext
, ptextLen
,
385 hmacAlg
, keySizeInBytes
,
386 stagedOrig
, stagedClone
, quiet
, verbose
)) {
390 if(pauseInterval
&& ((loop
% pauseInterval
) == 0)) {
393 printf("Hit CR to proceed, q to abort: ");
399 if(loops
&& (loop
== loops
)) {
412 printf("ModuleDetach/Unload complete; hit CR to exit: ");
415 if((rtn
== 0) && !quiet
) {
416 printf("%s test complete\n", argv
[0]);