]>
git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/ccHmacCompat/ccHmacCompat.c
2 * ccHmacCompat.c - test compatibilty of CommonCrypto's HMAC implementation with
5 * Written by Doug Mitchell.
13 #include <CommonCrypto/CommonHMAC.h>
14 #include <openssl/hmac.h>
16 /* SHA2-based HMAC testing disabled until openssl provides it */
17 #define HMAC_SHA2_ENABLE 0
24 #define MIN_DATA_SIZE 8
25 #define MAX_DATA_SIZE 10000 /* bytes */
26 #define MIN_KEY_SIZE 1
27 #define MAX_KEY_SIZE 256 /* bytes */
28 #define LOOP_NOTIFY 20
31 * Enumerate algs our own way to allow iteration.
41 #define ALG_FIRST ALG_MD5
43 #define ALG_LAST ALG_SHA512
45 #define ALG_LAST ALG_SHA1
46 #endif /* HMAC_SHA2_ENABLE */
50 #define logSize(s) printf s
55 static void usage(char **argv
)
57 printf("usage: %s [options]\n", argv
[0]);
58 printf(" Options:\n");
59 printf(" a=algorithm (5=MD5; s=SHA1; 4=SHA224; 2=SHA256; 3=SHA384; 1=SHA512; default=all)\n");
60 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF
);
61 printf(" k=keySizeInBytes\n");
62 printf(" m=maxPtextSize (default=%d)\n", MAX_DATA_SIZE
);
63 printf(" n=minPtextSize (default=%d)\n", MIN_DATA_SIZE
);
64 printf(" p=pauseInterval (default=0, no pause)\n");
65 printf(" s (all ops single-shot, not staged)\n");
66 printf(" z (keys and plaintext all zeroes)\n");
67 printf(" v(erbose)\n");
74 * Test harness for CCCryptor/HMAC with lots of options.
77 CCHmacAlgorithm hmacAlg
, bool randUpdates
,
78 const void *keyBytes
, size_t keyLen
,
79 const uint8_t *inText
, size_t inTextLen
,
80 uint8_t *outText
) /* returned, caller mallocs */
83 size_t toMove
; /* total to go */
88 CCHmac(hmacAlg
, keyBytes
, keyLen
, inText
, inTextLen
, outText
);
92 /* random multi updates */
93 CCHmacInit(&ctx
, hmacAlg
, keyBytes
, keyLen
);
95 toMove
= inTextLen
; /* total to go */
96 inp
= (const uint8
*)inText
;
99 uint32 thisMoveIn
; /* input to CCryptUpdate() */
101 thisMoveIn
= genRand(1, toMove
);
102 logSize(("###ptext segment len %lu\n", (unsigned long)thisMoveIn
));
103 CCHmacUpdate(&ctx
, inp
, thisMoveIn
);
105 toMove
-= thisMoveIn
;
108 CCHmacFinal(&ctx
, outText
);
112 * Produce HMAC with reference implementation (currently, openssl)
114 static int doHmacRef(
115 CCHmacAlgorithm hmacAlg
,
116 const void *keyBytes
, size_t keyLen
,
117 const uint8_t *inText
, size_t inTextLen
,
118 uint8_t *outText
, size_t *outTextLen
) /* caller mallocs */
130 case kCCHmacAlgSHA224
:
133 case kCCHmacAlgSHA256
:
136 case kCCHmacAlgSHA384
:
139 case kCCHmacAlgSHA512
:
142 #endif /* HMAC_SHA2_ENABLE */
144 printf("***Bad hmacAlg (%d)\n", (int)hmacAlg
);
147 unsigned md_len
= *outTextLen
;
148 HMAC(md
, keyBytes
, (int)keyLen
,
149 (const unsigned char *)inText
, (int)inTextLen
,
150 (unsigned char *)outText
, &md_len
);
151 *outTextLen
= md_len
;
157 #define MAX_HMAC_SIZE CC_SHA512_DIGEST_LENGTH
159 static int doTest(const uint8_t *ptext
,
161 CCHmacAlgorithm hmacAlg
,
162 uint32 keySizeInBytes
,
167 uint8_t keyBytes
[MAX_KEY_SIZE
];
168 uint8_t hmacCC
[MAX_HMAC_SIZE
];
170 uint8_t hmacRef
[MAX_HMAC_SIZE
];
175 memset(keyBytes
, 0, keySizeInBytes
);
179 appGetRandomBytes(keyBytes
, keySizeInBytes
);
182 hmacCCLen
= MAX_HMAC_SIZE
;
183 doHmacCC(hmacAlg
, staged
,
184 keyBytes
, keySizeInBytes
,
188 hmacRefLen
= MAX_HMAC_SIZE
;
189 rtn
= doHmacRef(hmacAlg
,
190 keyBytes
, keySizeInBytes
,
192 hmacRef
, &hmacRefLen
);
194 rtn
= testError(quiet
);
200 if(memcmp(hmacRef
, hmacCC
, hmacRefLen
)) {
201 printf("***data miscompare\n");
202 rtn
= testError(quiet
);
208 bool isBitSet(unsigned bit
, unsigned word
)
211 printf("We don't have that many bits\n");
214 unsigned mask
= 1 << bit
;
215 return (word
& mask
) ? true : false;
218 int main(int argc
, char **argv
)
227 CCHmacAlgorithm hmacAlg
;
229 int currAlg
; // ALG_xxx
230 uint32 keySizeInBytes
;
236 bool keySizeSpec
= false; // false: use rand key size
237 HmacAlg minAlg
= ALG_FIRST
;
238 HmacAlg maxAlg
= ALG_LAST
;
239 unsigned loops
= LOOPS_DEF
;
240 bool verbose
= false;
241 size_t minPtextSize
= MIN_DATA_SIZE
;
242 size_t maxPtextSize
= MAX_DATA_SIZE
;
244 unsigned pauseInterval
= 0;
245 bool stagedSpec
= false; // ditto for stagedEncr and stagedDecr
246 bool allZeroes
= false;
248 for(arg
=1; arg
<argc
; arg
++) {
257 minAlg
= maxAlg
= ALG_MD5
;
260 minAlg
= maxAlg
= ALG_SHA1
;
263 minAlg
= maxAlg
= ALG_SHA256
;
266 minAlg
= maxAlg
= ALG_SHA384
;
269 minAlg
= maxAlg
= ALG_SHA512
;
276 loops
= atoi(&argp
[2]);
279 minPtextSize
= atoi(&argp
[2]);
282 maxPtextSize
= atoi(&argp
[2]);
285 keySizeInBytes
= atoi(&argp
[2]);
295 pauseInterval
= atoi(&argp
[2]);;
309 ptext
= (uint8
*)malloc(maxPtextSize
);
311 printf("Insufficient heap space\n");
314 /* ptext length set in test loop */
316 memset(ptext
, 0, maxPtextSize
);
319 printf("Starting ccHmacCompat; args: ");
320 for(i
=1; i
<argc
; i
++) {
321 printf("%s ", argv
[i
]);
327 printf("Top of test; hit CR to proceed: ");
331 for(currAlg
=minAlg
; currAlg
<=maxAlg
; currAlg
++) {
332 /* when zero, set size randomly or per user setting */
335 hmacAlg
= kCCHmacAlgMD5
;
339 hmacAlg
= kCCHmacAlgSHA1
;
343 hmacAlg
= kCCHmacAlgSHA256
;
344 algStr
= "HMACSHA256";
347 hmacAlg
= kCCHmacAlgSHA384
;
348 algStr
= "HMACSHA384";
351 hmacAlg
= kCCHmacAlgSHA512
;
352 algStr
= "HMACSHA512";
355 printf("***BRRZAP!\n");
358 if(!quiet
|| verbose
) {
359 printf("Testing alg %s\n", algStr
);
361 for(loop
=1; ; loop
++) {
362 ptextLen
= genRand(minPtextSize
, maxPtextSize
);
364 appGetRandomBytes(ptext
, ptextLen
);
367 keySizeInBytes
= genRand(MIN_KEY_SIZE
, MAX_KEY_SIZE
);
370 /* per-loop settings */
372 staged
= isBitSet(1, loop
);
376 if(verbose
|| ((loop
% LOOP_NOTIFY
) == 0)) {
377 printf("..loop %d ptextLen %lu keySize %lu staged=%d\n",
378 loop
, (unsigned long)ptextLen
, (unsigned long)keySizeInBytes
,
383 if(doTest(ptext
, ptextLen
,
384 hmacAlg
, keySizeInBytes
,
385 staged
, allZeroes
, quiet
)) {
389 if(pauseInterval
&& ((loop
% pauseInterval
) == 0)) {
392 printf("Hit CR to proceed, q to abort: ");
398 if(loops
&& (loop
== loops
)) {
411 printf("ModuleDetach/Unload complete; hit CR to exit: ");
414 if((rtn
== 0) && !quiet
) {
415 printf("%s test complete\n", argv
[0]);