1 /*
2 ** SQLCipher
3 ** http://sqlcipher.net
4 **
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
7 **
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.
18 **
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.
29 **
30 */
31 /* BEGIN SQLCIPHER */
32 #ifdef SQLITE_HAS_CODEC
33 #ifdef SQLCIPHER_CRYPTO_CC
34 #include "crypto.h"
35 #include "sqlcipher.h"
36 #include <CommonCrypto/CommonCrypto.h>
37 #include <Security/SecRandom.h>
38 #include <CoreFoundation/CoreFoundation.h>
39 
sqlcipher_cc_add_random(void * ctx,void * buffer,int length)40 static int sqlcipher_cc_add_random(void *ctx, void *buffer, int length) {
41   return SQLITE_OK;
42 }
43 
44 /* generate a defined number of random bytes */
sqlcipher_cc_random(void * ctx,void * buffer,int length)45 static int sqlcipher_cc_random (void *ctx, void *buffer, int length) {
46   return (SecRandomCopyBytes(kSecRandomDefault, length, (uint8_t *)buffer) == 0) ? SQLITE_OK : SQLITE_ERROR;
47 }
48 
sqlcipher_cc_get_provider_name(void * ctx)49 static const char* sqlcipher_cc_get_provider_name(void *ctx) {
50   return "commoncrypto";
51 }
52 
sqlcipher_cc_get_provider_version(void * ctx)53 static const char* sqlcipher_cc_get_provider_version(void *ctx) {
54 #if TARGET_OS_MAC
55   CFTypeRef version;
56   CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
57   if(bundle == NULL) {
58     return "unknown";
59   }
60   version = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
61   return CFStringGetCStringPtr(version, kCFStringEncodingUTF8);
62 #else
63   return "unknown";
64 #endif
65 }
66 
sqlcipher_cc_hmac(void * ctx,unsigned char * hmac_key,int key_sz,unsigned char * in,int in_sz,unsigned char * in2,int in2_sz,unsigned char * out)67 static int sqlcipher_cc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
68   CCHmacContext hmac_context;
69   if(in == NULL) return SQLITE_ERROR;
70   CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
71   CCHmacUpdate(&hmac_context, in, in_sz);
72   if(in2 != NULL) CCHmacUpdate(&hmac_context, in2, in2_sz);
73   CCHmacFinal(&hmac_context, out);
74   return SQLITE_OK;
75 }
76 
sqlcipher_cc_kdf(void * ctx,const unsigned char * pass,int pass_sz,unsigned char * salt,int salt_sz,int workfactor,int key_sz,unsigned char * key)77 static int sqlcipher_cc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
78   CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, workfactor, key, key_sz);
79   return SQLITE_OK;
80 }
81 
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)82 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) {
83   CCCryptorRef cryptor;
84   size_t tmp_csz, csz;
85   CCOperation op = mode == CIPHER_ENCRYPT ? kCCEncrypt : kCCDecrypt;
86 
87   CCCryptorCreate(op, kCCAlgorithmAES128, 0, key, kCCKeySizeAES256, iv, &cryptor);
88   CCCryptorUpdate(cryptor, in, in_sz, out, in_sz, &tmp_csz);
89   csz = tmp_csz;
90   out += tmp_csz;
91   CCCryptorFinal(cryptor, out, in_sz - csz, &tmp_csz);
92   csz += tmp_csz;
93   CCCryptorRelease(cryptor);
94   assert(in_sz == csz);
95 
96   return SQLITE_OK;
97 }
98 
sqlcipher_cc_set_cipher(void * ctx,const char * cipher_name)99 static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) {
100   return SQLITE_OK;
101 }
102 
sqlcipher_cc_get_cipher(void * ctx)103 static const char* sqlcipher_cc_get_cipher(void *ctx) {
104   return "aes-256-cbc";
105 }
106 
sqlcipher_cc_get_key_sz(void * ctx)107 static int sqlcipher_cc_get_key_sz(void *ctx) {
108   return kCCKeySizeAES256;
109 }
110 
sqlcipher_cc_get_iv_sz(void * ctx)111 static int sqlcipher_cc_get_iv_sz(void *ctx) {
112   return kCCBlockSizeAES128;
113 }
114 
sqlcipher_cc_get_block_sz(void * ctx)115 static int sqlcipher_cc_get_block_sz(void *ctx) {
116   return kCCBlockSizeAES128;
117 }
118 
sqlcipher_cc_get_hmac_sz(void * ctx)119 static int sqlcipher_cc_get_hmac_sz(void *ctx) {
120   return CC_SHA1_DIGEST_LENGTH;
121 }
122 
sqlcipher_cc_ctx_copy(void * target_ctx,void * source_ctx)123 static int sqlcipher_cc_ctx_copy(void *target_ctx, void *source_ctx) {
124   return SQLITE_OK;
125 }
126 
sqlcipher_cc_ctx_cmp(void * c1,void * c2)127 static int sqlcipher_cc_ctx_cmp(void *c1, void *c2) {
128   return 1; /* always indicate contexts are the same */
129 }
130 
sqlcipher_cc_ctx_init(void ** ctx)131 static int sqlcipher_cc_ctx_init(void **ctx) {
132   return SQLITE_OK;
133 }
134 
sqlcipher_cc_ctx_free(void ** ctx)135 static int sqlcipher_cc_ctx_free(void **ctx) {
136   return SQLITE_OK;
137 }
138 
sqlcipher_cc_fips_status(void * ctx)139 static int sqlcipher_cc_fips_status(void *ctx) {
140   return 0;
141 }
142 
sqlcipher_cc_setup(sqlcipher_provider * p)143 int sqlcipher_cc_setup(sqlcipher_provider *p) {
144   p->random = sqlcipher_cc_random;
145   p->get_provider_name = sqlcipher_cc_get_provider_name;
146   p->hmac = sqlcipher_cc_hmac;
147   p->kdf = sqlcipher_cc_kdf;
148   p->cipher = sqlcipher_cc_cipher;
149   p->set_cipher = sqlcipher_cc_set_cipher;
150   p->get_cipher = sqlcipher_cc_get_cipher;
151   p->get_key_sz = sqlcipher_cc_get_key_sz;
152   p->get_iv_sz = sqlcipher_cc_get_iv_sz;
153   p->get_block_sz = sqlcipher_cc_get_block_sz;
154   p->get_hmac_sz = sqlcipher_cc_get_hmac_sz;
155   p->ctx_copy = sqlcipher_cc_ctx_copy;
156   p->ctx_cmp = sqlcipher_cc_ctx_cmp;
157   p->ctx_init = sqlcipher_cc_ctx_init;
158   p->ctx_free = sqlcipher_cc_ctx_free;
159   p->add_random = sqlcipher_cc_add_random;
160   p->fips_status = sqlcipher_cc_fips_status;
161   p->get_provider_version = sqlcipher_cc_get_provider_version;
162   return SQLITE_OK;
163 }
164 
165 #endif
166 #endif
167 /* END SQLCIPHER */
168