Merge branch 'nd/list-merge-strategy'
[git] / compat / apple-common-crypto.h
1 /* suppress inclusion of conflicting openssl functions */
2 #define OPENSSL_NO_MD5
3 #define HEADER_HMAC_H
4 #define HEADER_SHA_H
5 #include <CommonCrypto/CommonHMAC.h>
6 #define EVP_md5(...) kCCHmacAlgMD5
7 /* CCHmac doesn't take md_len and the return type is void */
8 #define HMAC git_CC_HMAC
9 static inline unsigned char *git_CC_HMAC(CCHmacAlgorithm alg,
10                 const void *key, int key_len,
11                 const unsigned char *data, size_t data_len,
12                 unsigned char *md, unsigned int *md_len)
13 {
14         CCHmac(alg, key, key_len, data, data_len, md);
15         return md;
16 }
17
18 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
19 #define APPLE_LION_OR_NEWER
20 #include <Security/Security.h>
21 /* Apple's TYPE_BOOL conflicts with config.c */
22 #undef TYPE_BOOL
23 #endif
24
25 #ifndef SHA1_MAX_BLOCK_SIZE
26 #error Using Apple Common Crypto library requires setting SHA1_MAX_BLOCK_SIZE
27 #endif
28
29 #ifdef APPLE_LION_OR_NEWER
30 #define git_CC_error_check(pattern, err) \
31         do { \
32                 if (err) { \
33                         die(pattern, (long)CFErrorGetCode(err)); \
34                 } \
35         } while(0)
36
37 #define EVP_EncodeBlock git_CC_EVP_EncodeBlock
38 static inline int git_CC_EVP_EncodeBlock(unsigned char *out,
39                 const unsigned char *in, int inlen)
40 {
41         CFErrorRef err;
42         SecTransformRef encoder;
43         CFDataRef input, output;
44         CFIndex length;
45
46         encoder = SecEncodeTransformCreate(kSecBase64Encoding, &err);
47         git_CC_error_check("SecEncodeTransformCreate failed: %ld", err);
48
49         input = CFDataCreate(kCFAllocatorDefault, in, inlen);
50         SecTransformSetAttribute(encoder, kSecTransformInputAttributeName,
51                         input, &err);
52         git_CC_error_check("SecTransformSetAttribute failed: %ld", err);
53
54         output = SecTransformExecute(encoder, &err);
55         git_CC_error_check("SecTransformExecute failed: %ld", err);
56
57         length = CFDataGetLength(output);
58         CFDataGetBytes(output, CFRangeMake(0, length), out);
59
60         CFRelease(output);
61         CFRelease(input);
62         CFRelease(encoder);
63
64         return (int)strlen((const char *)out);
65 }
66
67 #define EVP_DecodeBlock git_CC_EVP_DecodeBlock
68 static int inline git_CC_EVP_DecodeBlock(unsigned char *out,
69                 const unsigned char *in, int inlen)
70 {
71         CFErrorRef err;
72         SecTransformRef decoder;
73         CFDataRef input, output;
74         CFIndex length;
75
76         decoder = SecDecodeTransformCreate(kSecBase64Encoding, &err);
77         git_CC_error_check("SecEncodeTransformCreate failed: %ld", err);
78
79         input = CFDataCreate(kCFAllocatorDefault, in, inlen);
80         SecTransformSetAttribute(decoder, kSecTransformInputAttributeName,
81                         input, &err);
82         git_CC_error_check("SecTransformSetAttribute failed: %ld", err);
83
84         output = SecTransformExecute(decoder, &err);
85         git_CC_error_check("SecTransformExecute failed: %ld", err);
86
87         length = CFDataGetLength(output);
88         CFDataGetBytes(output, CFRangeMake(0, length), out);
89
90         CFRelease(output);
91         CFRelease(input);
92         CFRelease(decoder);
93
94         return (int)strlen((const char *)out);
95 }
96 #endif /* APPLE_LION_OR_NEWER */