1#include <stdio.h>
2#include "testbyteBuffer.h"
3#include "capabilities.h"
4#include "testmore.h"
5#include <string.h>
6#include <CommonCrypto/CommonDigest.h>
7
8#if (CCBIGDIGEST == 0)
9entryPoint(CommonBigDigest,"CommonCrypto CCDigest Large Size test")
10#else
11#include <CommonCrypto/CommonDigestSPI.h>
12#include <stdlib.h>
13
14static const size_t blocksz = (size_t) 0x40000000; // 1 GB
15static const size_t testsz = (size_t) 0x140000000; // 5 GB
16
17static void DigestInChunks(CCDigestAlgorithm algorithm, size_t chunksize, const uint8_t *bytesToDigest, size_t numbytes, uint8_t *outbuf)
18{
19    CCDigestRef d = CCDigestCreate(algorithm);
20    while(numbytes) {
21        size_t n = (numbytes < chunksize) ? numbytes: chunksize;
22        CCDigestUpdate(d, bytesToDigest, n);
23        numbytes -= n; bytesToDigest += n;
24    }
25    if(CCDigestFinal(d, outbuf)) return;
26    CCDigestDestroy(d);
27}
28
29/*
30 * Compute the digest of a whole file
31 */
32
33static int
34checksum_mem(uint8_t *memptr, CCDigestAlgorithm algorithm)
35{
36    size_t digestsize = CCDigestGetOutputSize(algorithm);
37    uint8_t mdwhole[digestsize];
38    uint8_t mdchunk[digestsize];
39
40	/*
41	 * First do it in one big chunk
42	 */
43
44    CCDigest(algorithm, memptr, testsz, mdwhole);
45
46	/*
47	 * Now do it in several 1GB chunks
48	 */
49
50    DigestInChunks(algorithm, blocksz, memptr, testsz, mdchunk);
51
52    int cmpval = memcmp(mdchunk, mdwhole, digestsize);
53    ok(cmpval == 0, "Results are the same for both digests");
54
55    return 0;
56}
57
58static inline uint8_t *
59getMemoryPattern() {
60    uint8_t *retval = malloc(testsz);
61    if(!retval) return retval;
62    for(size_t i=0; i<testsz; i++) retval[i] = i & 0xff;
63    return retval;
64}
65
66static const int kTestTestCount = 1;
67
68int CommonBigDigest(int argc, char *const *argv)
69{
70    plan_tests(kTestTestCount);
71    uint8_t *memptr = getMemoryPattern();
72    if(memptr) {
73        checksum_mem(memptr, kCCDigestSHA1);
74        free(memptr);
75    } else {
76        ok(1, "can't get enough memory");
77        diag("Can't check large digest correctness - failed to alloc memory\n");
78    }
79    return 0;
80}
81
82
83#endif
84