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
35 #include "sqlcipher.h"
36 #include <CommonCrypto/CommonCrypto.h>
37 #include <Security/SecRandom.h>
38 #include <CoreFoundation/CoreFoundation.h>
40 int sqlcipher_cc_setup(sqlcipher_provider
*p
);
42 static int sqlcipher_cc_add_random(void *ctx
, void *buffer
, int length
) {
46 /* generate a defined number of random bytes */
47 static int sqlcipher_cc_random (void *ctx
, void *buffer
, int length
) {
48 return (SecRandomCopyBytes(kSecRandomDefault
, length
, (uint8_t *)buffer
) == kCCSuccess
) ? SQLITE_OK
: SQLITE_ERROR
;
51 static const char* sqlcipher_cc_get_provider_name(void *ctx
) {
52 return "commoncrypto";
55 static const char* sqlcipher_cc_get_provider_version(void *ctx
) {
58 CFBundleRef bundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
62 version
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("CFBundleShortVersionString"));
63 return CFStringGetCStringPtr(version
, kCFStringEncodingUTF8
);
69 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
) {
70 CCHmacContext hmac_context
;
71 if(in
== NULL
) return SQLITE_ERROR
;
73 case SQLCIPHER_HMAC_SHA1
:
74 CCHmacInit(&hmac_context
, kCCHmacAlgSHA1
, hmac_key
, key_sz
);
76 case SQLCIPHER_HMAC_SHA256
:
77 CCHmacInit(&hmac_context
, kCCHmacAlgSHA256
, hmac_key
, key_sz
);
79 case SQLCIPHER_HMAC_SHA512
:
80 CCHmacInit(&hmac_context
, kCCHmacAlgSHA512
, hmac_key
, key_sz
);
85 CCHmacUpdate(&hmac_context
, in
, in_sz
);
86 if(in2
!= NULL
) CCHmacUpdate(&hmac_context
, in2
, in2_sz
);
87 CCHmacFinal(&hmac_context
, out
);
91 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
) {
93 case SQLCIPHER_HMAC_SHA1
:
94 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA1
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
96 case SQLCIPHER_HMAC_SHA256
:
97 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA256
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
99 case SQLCIPHER_HMAC_SHA512
:
100 if(CCKeyDerivationPBKDF(kCCPBKDF2
, (const char *)pass
, pass_sz
, salt
, salt_sz
, kCCPRFHmacAlgSHA512
, workfactor
, key
, key_sz
) != kCCSuccess
) return SQLITE_ERROR
;
108 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
) {
109 CCCryptorRef cryptor
;
111 CCOperation op
= mode
== CIPHER_ENCRYPT
? kCCEncrypt
: kCCDecrypt
;
113 if(CCCryptorCreate(op
, kCCAlgorithmAES128
, 0, key
, kCCKeySizeAES256
, iv
, &cryptor
) != kCCSuccess
) return SQLITE_ERROR
;
114 if(CCCryptorUpdate(cryptor
, in
, in_sz
, out
, in_sz
, &tmp_csz
) != kCCSuccess
) return SQLITE_ERROR
;
117 if(CCCryptorFinal(cryptor
, out
, in_sz
- csz
, &tmp_csz
) != kCCSuccess
) return SQLITE_ERROR
;
119 if(CCCryptorRelease(cryptor
) != kCCSuccess
) return SQLITE_ERROR
;
120 assert(in_sz
== csz
);
125 static const char* sqlcipher_cc_get_cipher(void *ctx
) {
126 return "aes-256-cbc";
129 static int sqlcipher_cc_get_key_sz(void *ctx
) {
130 return kCCKeySizeAES256
;
133 static int sqlcipher_cc_get_iv_sz(void *ctx
) {
134 return kCCBlockSizeAES128
;
137 static int sqlcipher_cc_get_block_sz(void *ctx
) {
138 return kCCBlockSizeAES128
;
141 static int sqlcipher_cc_get_hmac_sz(void *ctx
, int algorithm
) {
143 case SQLCIPHER_HMAC_SHA1
:
144 return CC_SHA1_DIGEST_LENGTH
;
146 case SQLCIPHER_HMAC_SHA256
:
147 return CC_SHA256_DIGEST_LENGTH
;
149 case SQLCIPHER_HMAC_SHA512
:
150 return CC_SHA512_DIGEST_LENGTH
;
157 static int sqlcipher_cc_ctx_init(void **ctx
) {
161 static int sqlcipher_cc_ctx_free(void **ctx
) {
165 static int sqlcipher_cc_fips_status(void *ctx
) {
169 int sqlcipher_cc_setup(sqlcipher_provider
*p
) {
170 p
->random
= sqlcipher_cc_random
;
171 p
->get_provider_name
= sqlcipher_cc_get_provider_name
;
172 p
->hmac
= sqlcipher_cc_hmac
;
173 p
->kdf
= sqlcipher_cc_kdf
;
174 p
->cipher
= sqlcipher_cc_cipher
;
175 p
->get_cipher
= sqlcipher_cc_get_cipher
;
176 p
->get_key_sz
= sqlcipher_cc_get_key_sz
;
177 p
->get_iv_sz
= sqlcipher_cc_get_iv_sz
;
178 p
->get_block_sz
= sqlcipher_cc_get_block_sz
;
179 p
->get_hmac_sz
= sqlcipher_cc_get_hmac_sz
;
180 p
->ctx_init
= sqlcipher_cc_ctx_init
;
181 p
->ctx_free
= sqlcipher_cc_ctx_free
;
182 p
->add_random
= sqlcipher_cc_add_random
;
183 p
->fips_status
= sqlcipher_cc_fips_status
;
184 p
->get_provider_version
= sqlcipher_cc_get_provider_version
;