3 ** http://sqlcipher.net
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions are met:
10 ** * Redistributions of source code must retain the above copyright
11 ** notice, this list of conditions and the following disclaimer.
12 ** * Redistributions in binary form must reproduce the above copyright
13 ** notice, this list of conditions and the following disclaimer in the
14 ** documentation and/or other materials provided with the distribution.
15 ** * Neither the name of the ZETETIC LLC nor the
16 ** names of its contributors may be used to endorse or promote products
17 ** derived from this software without specific prior written permission.
19 ** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
20 ** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 ** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
23 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifdef SQLITE_HAS_CODEC
33 #ifdef SQLCIPHER_CRYPTO_CC
34 #include "sqlcipher.h"
35 #include <CommonCrypto/CommonCrypto.h>
36 #include <Security/SecRandom.h>
37 #include <CoreFoundation/CoreFoundation.h>
39 int sqlcipher_cc_setup(sqlcipher_provider
*p
);
41 static int sqlcipher_cc_add_random(void *ctx
, void *buffer
, int length
) {
45 /* generate a defined number of random bytes */
46 static int sqlcipher_cc_random (void *ctx
, void *buffer
, int length
) {
47 return (SecRandomCopyBytes(kSecRandomDefault
, length
, (uint8_t *)buffer
) == kCCSuccess
) ? SQLITE_OK
: SQLITE_ERROR
;
50 static const char* sqlcipher_cc_get_provider_name(void *ctx
) {
51 return "commoncrypto";
54 static const char* sqlcipher_cc_get_provider_version(void *ctx
) {
57 CFBundleRef bundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
61 version
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("CFBundleShortVersionString"));
62 return CFStringGetCStringPtr(version
, kCFStringEncodingUTF8
);
68 static int sqlcipher_cc_hmac(void *ctx
, int algorithm
, unsigned char *hmac_key
, int key_sz
, unsigned char *in
, int in_sz
, unsigned char *in2
, int in2_sz
, unsigned char *out
) {
69 CCHmacContext hmac_context
;
70 if(in
== NULL
) return SQLITE_ERROR
;
72 case SQLCIPHER_HMAC_SHA1
:
73 CCHmacInit(&hmac_context
, kCCHmacAlgSHA1
, hmac_key
, key_sz
);
75 case SQLCIPHER_HMAC_SHA256
:
76 CCHmacInit(&hmac_context
, kCCHmacAlgSHA256
, hmac_key
, key_sz
);
78 case SQLCIPHER_HMAC_SHA512
:
79 CCHmacInit(&hmac_context
, kCCHmacAlgSHA512
, hmac_key
, key_sz
);
84 CCHmacUpdate(&hmac_context
, in
, in_sz
);
85 if(in2
!= NULL
) CCHmacUpdate(&hmac_context
, in2
, in2_sz
);
86 CCHmacFinal(&hmac_context
, out
);
90 static int sqlcipher_cc_kdf(void *ctx
, int algorithm
, const unsigned char *pass
, int pass_sz
, unsigned char* salt
, int salt_sz
, int workfactor
, int key_sz
, unsigned char *key
) {
92 case SQLCIPHER_HMAC_SHA1
:
93 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA1
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
95 case SQLCIPHER_HMAC_SHA256
:
96 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA256
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
98 case SQLCIPHER_HMAC_SHA512
:
99 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA512
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
107 static int sqlcipher_cc_cipher(void *ctx
, int mode
, unsigned char *key
, int key_sz
, unsigned char *iv
, unsigned char *in
, int in_sz
, unsigned char *out
) {
108 CCCryptorRef cryptor
;
110 CCOperation op
= mode
== CIPHER_ENCRYPT
? kCCEncrypt
: kCCDecrypt
;
112 if(CCCryptorCreate(op
, kCCAlgorithmAES128
, 0, key
, kCCKeySizeAES256
, iv
, &cryptor
) != kCCSuccess
) return SQLITE_ERROR
;
113 if(CCCryptorUpdate(cryptor
, in
, in_sz
, out
, in_sz
, &tmp_csz
) != kCCSuccess
) return SQLITE_ERROR
;
116 if(CCCryptorFinal(cryptor
, out
, in_sz
- csz
, &tmp_csz
) != kCCSuccess
) return SQLITE_ERROR
;
118 if(CCCryptorRelease(cryptor
) != kCCSuccess
) return SQLITE_ERROR
;
119 assert(in_sz
== csz
);
124 static const char* sqlcipher_cc_get_cipher(void *ctx
) {
125 return "aes-256-cbc";
128 static int sqlcipher_cc_get_key_sz(void *ctx
) {
129 return kCCKeySizeAES256
;
132 static int sqlcipher_cc_get_iv_sz(void *ctx
) {
133 return kCCBlockSizeAES128
;
136 static int sqlcipher_cc_get_block_sz(void *ctx
) {
137 return kCCBlockSizeAES128
;
140 static int sqlcipher_cc_get_hmac_sz(void *ctx
, int algorithm
) {
142 case SQLCIPHER_HMAC_SHA1
:
143 return CC_SHA1_DIGEST_LENGTH
;
145 case SQLCIPHER_HMAC_SHA256
:
146 return CC_SHA256_DIGEST_LENGTH
;
148 case SQLCIPHER_HMAC_SHA512
:
149 return CC_SHA512_DIGEST_LENGTH
;
156 static int sqlcipher_cc_ctx_init(void **ctx
) {
160 static int sqlcipher_cc_ctx_free(void **ctx
) {
164 static int sqlcipher_cc_fips_status(void *ctx
) {
168 int sqlcipher_cc_setup(sqlcipher_provider
*p
) {
169 p
->random
= sqlcipher_cc_random
;
170 p
->get_provider_name
= sqlcipher_cc_get_provider_name
;
171 p
->hmac
= sqlcipher_cc_hmac
;
172 p
->kdf
= sqlcipher_cc_kdf
;
173 p
->cipher
= sqlcipher_cc_cipher
;
174 p
->get_cipher
= sqlcipher_cc_get_cipher
;
175 p
->get_key_sz
= sqlcipher_cc_get_key_sz
;
176 p
->get_iv_sz
= sqlcipher_cc_get_iv_sz
;
177 p
->get_block_sz
= sqlcipher_cc_get_block_sz
;
178 p
->get_hmac_sz
= sqlcipher_cc_get_hmac_sz
;
179 p
->ctx_init
= sqlcipher_cc_ctx_init
;
180 p
->ctx_free
= sqlcipher_cc_ctx_free
;
181 p
->add_random
= sqlcipher_cc_add_random
;
182 p
->fips_status
= sqlcipher_cc_fips_status
;
183 p
->get_provider_version
= sqlcipher_cc_get_provider_version
;