]>
git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/ccOneShot/ccOneShot.cpp
2 * ccOneShot.c - Ensure that one-shot CommonDigest routines behave correctly.
4 * Written 3/31/06 by Doug Mitchell.
12 #include <CommonCrypto/CommonDigest.h>
13 #include <openssl/hmac.h>
19 #define MIN_DATA_SIZE 1
20 #define MAX_DATA_SIZE 10000 /* bytes */
21 #define LOOP_NOTIFY 20
24 * Enumerate algs our own way to allow iteration.
36 #define ALG_FIRST ALG_MD2
37 #define ALG_LAST ALG_SHA512
39 static void usage(char **argv
)
41 printf("usage: %s [options]\n", argv
[0]);
42 printf(" Options:\n");
43 printf(" l=loops (default %d)\n", LOOPS_DEF
);
49 /* the context pointers are void * here for polymorphism later on */
50 typedef int (*initFcn
)(void *ctx
);
51 typedef int (*updateFcn
)(void *ctx
, const void *data
, CC_LONG len
);
52 typedef int (*finalFcn
)(unsigned char *md
, void *ctx
);
53 typedef unsigned char (*oneShotFcn
)(const void *data
, CC_LONG len
, unsigned char *md
);
65 /* casts are necessary to cover the void* context args */
66 static const CommonDigestInfo digests
[] =
68 { ALG_MD2
, "MD2", CC_MD2_DIGEST_LENGTH
,
69 (initFcn
)CC_MD2_Init
, (updateFcn
)CC_MD2_Update
,
70 (finalFcn
)CC_MD2_Final
, (oneShotFcn
)CC_MD2
72 { ALG_MD4
, "MD4", CC_MD4_DIGEST_LENGTH
,
73 (initFcn
)CC_MD4_Init
, (updateFcn
)CC_MD4_Update
,
74 (finalFcn
)CC_MD4_Final
, (oneShotFcn
)CC_MD4
76 { ALG_MD5
, "MD5", CC_MD5_DIGEST_LENGTH
,
77 (initFcn
)CC_MD5_Init
, (updateFcn
)CC_MD5_Update
,
78 (finalFcn
)CC_MD5_Final
, (oneShotFcn
)CC_MD5
80 { ALG_SHA1
, "SHA1", CC_SHA1_DIGEST_LENGTH
,
81 (initFcn
)CC_SHA1_Init
, (updateFcn
)CC_SHA1_Update
,
82 (finalFcn
)CC_SHA1_Final
, (oneShotFcn
)CC_SHA1
84 { ALG_SHA224
, "SHA224", CC_SHA224_DIGEST_LENGTH
,
85 (initFcn
)CC_SHA224_Init
, (updateFcn
)CC_SHA224_Update
,
86 (finalFcn
)CC_SHA224_Final
, (oneShotFcn
)CC_SHA224
88 { ALG_SHA256
, "SHA256", CC_SHA256_DIGEST_LENGTH
,
89 (initFcn
)CC_SHA256_Init
, (updateFcn
)CC_SHA256_Update
,
90 (finalFcn
)CC_SHA256_Final
, (oneShotFcn
)CC_SHA256
92 { ALG_SHA384
, "SHA384", CC_SHA384_DIGEST_LENGTH
,
93 (initFcn
)CC_SHA384_Init
, (updateFcn
)CC_SHA384_Update
,
94 (finalFcn
)CC_SHA384_Final
, (oneShotFcn
)CC_SHA384
96 { ALG_SHA512
, "SHA512", CC_SHA512_DIGEST_LENGTH
,
97 (initFcn
)CC_SHA512_Init
, (updateFcn
)CC_SHA512_Update
,
98 (finalFcn
)CC_SHA512_Final
, (oneShotFcn
)CC_SHA512
101 #define NUM_DIGESTS (sizeof(digests) / sizeof(digests[0]))
103 static const CommonDigestInfo
*findDigestInfo(unsigned alg
)
106 for(dex
=0; dex
<NUM_DIGESTS
; dex
++) {
107 if((unsigned)(digests
[dex
].alg
) == alg
) {
108 return &digests
[dex
];
116 * These consts let us allocate context and digest buffers for
117 * any arbitrary algorithm.
119 #define MAX_DIGEST_SIZE 64
120 #define MAX_CONTEXT_SIZE sizeof(CC_SHA512_CTX)
122 /* staged digest with random updates */
123 static void doStaged(
124 const CommonDigestInfo
*digestInfo
,
125 const unsigned char *ptext
,
129 char ctx
[MAX_CONTEXT_SIZE
];
132 digestInfo
->init(ctx
);
134 thisMove
= genRand(1, ptextLen
);
135 digestInfo
->update(ctx
, ptext
, thisMove
);
137 ptextLen
-= thisMove
;
139 digestInfo
->final(md
, ctx
);
143 const CommonDigestInfo
*digestInfo
,
144 const unsigned char *ptext
,
148 unsigned char mdStaged
[MAX_DIGEST_SIZE
];
149 unsigned char mdOneShot
[MAX_DIGEST_SIZE
];
151 digestInfo
->oneShot(ptext
, ptextLen
, mdOneShot
);
152 doStaged(digestInfo
, ptext
, ptextLen
, mdStaged
);
153 if(memcmp(mdStaged
, mdOneShot
, digestInfo
->digestSize
)) {
154 printf("***Digest miscompare for %s\n", digestInfo
->algName
);
155 if(testError(quiet
)) {
162 int main(int argc
, char **argv
)
170 const CommonDigestInfo
*digestInfo
;
177 unsigned loops
= LOOPS_DEF
;
180 for(arg
=1; arg
<argc
; arg
++) {
184 loops
= atoi(&argp
[2]);
194 ptext
= (uint8
*)malloc(MAX_DATA_SIZE
);
196 printf("Insufficient heap space\n");
199 /* ptext length set in test loop */
201 printf("Starting ccOneShot; args: ");
202 for(i
=1; i
<argc
; i
++) {
203 printf("%s ", argv
[i
]);
207 for(currAlg
=ALG_FIRST
; currAlg
<=ALG_LAST
; currAlg
++) {
208 digestInfo
= findDigestInfo(currAlg
);
210 printf("Testing alg %s\n", digestInfo
->algName
);
212 for(loop
=1; ; loop
++) {
213 ptextLen
= genRand(MIN_DATA_SIZE
, MAX_DATA_SIZE
);
214 appGetRandomBytes(ptext
, ptextLen
);
216 if((loop
% LOOP_NOTIFY
) == 0) {
217 printf("..loop %d ptextLen %lu\n",
218 loop
, (unsigned long)ptextLen
);
222 if(doTest(digestInfo
, ptext
, ptextLen
, quiet
)) {
226 if(loops
&& (loop
== loops
)) {
236 if((rtn
== 0) && !quiet
) {
237 printf("%s test complete\n", argv
[0]);