Merges crypto.h, crypto.c, and crypto_impl.c into sqlcipher.c
[sqlcipher.git] / src / crypto_cc.c
blobf5942c298365f309075e5ae4b66a3a6e01766335
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.
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.
31 /* BEGIN SQLCIPHER */
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) {
42 return SQLITE_OK;
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) {
55 #if TARGET_OS_MAC
56 CFTypeRef version;
57 CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
58 if(bundle == NULL) {
59 return "unknown";
61 version = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
62 return CFStringGetCStringPtr(version, kCFStringEncodingUTF8);
63 #else
64 return "unknown";
65 #endif
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;
71 switch(algorithm) {
72 case SQLCIPHER_HMAC_SHA1:
73 CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
74 break;
75 case SQLCIPHER_HMAC_SHA256:
76 CCHmacInit(&hmac_context, kCCHmacAlgSHA256, hmac_key, key_sz);
77 break;
78 case SQLCIPHER_HMAC_SHA512:
79 CCHmacInit(&hmac_context, kCCHmacAlgSHA512, hmac_key, key_sz);
80 break;
81 default:
82 return SQLITE_ERROR;
84 CCHmacUpdate(&hmac_context, in, in_sz);
85 if(in2 != NULL) CCHmacUpdate(&hmac_context, in2, in2_sz);
86 CCHmacFinal(&hmac_context, out);
87 return SQLITE_OK;
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) {
91 switch(algorithm) {
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;
94 break;
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;
97 break;
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;
100 break;
101 default:
102 return SQLITE_ERROR;
104 return SQLITE_OK;
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;
109 size_t tmp_csz, csz;
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;
114 csz = tmp_csz;
115 out += tmp_csz;
116 if(CCCryptorFinal(cryptor, out, in_sz - csz, &tmp_csz) != kCCSuccess) return SQLITE_ERROR;
117 csz += tmp_csz;
118 if(CCCryptorRelease(cryptor) != kCCSuccess) return SQLITE_ERROR;
119 assert(in_sz == csz);
121 return SQLITE_OK;
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) {
141 switch(algorithm) {
142 case SQLCIPHER_HMAC_SHA1:
143 return CC_SHA1_DIGEST_LENGTH;
144 break;
145 case SQLCIPHER_HMAC_SHA256:
146 return CC_SHA256_DIGEST_LENGTH;
147 break;
148 case SQLCIPHER_HMAC_SHA512:
149 return CC_SHA512_DIGEST_LENGTH;
150 break;
151 default:
152 return 0;
156 static int sqlcipher_cc_ctx_init(void **ctx) {
157 return SQLITE_OK;
160 static int sqlcipher_cc_ctx_free(void **ctx) {
161 return SQLITE_OK;
164 static int sqlcipher_cc_fips_status(void *ctx) {
165 return 0;
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;
184 return SQLITE_OK;
187 #endif
188 #endif
189 /* END SQLCIPHER */