remove unused id and status from provider interface
[sqlcipher.git] / src / crypto_libtomcrypt.c
blobdba94abbb7a26c66d2bc7014f2fa0886e810fafa
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_LIBTOMCRYPT
34 #include "sqliteInt.h"
35 #include "sqlcipher.h"
36 #include <tomcrypt.h>
38 #define FORTUNA_MAX_SZ 32
39 static prng_state prng;
40 static volatile unsigned int ltc_init = 0;
41 static volatile unsigned int ltc_ref_count = 0;
43 #define LTC_CIPHER "rijndael"
45 static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
46 int rc = 0;
47 int data_to_read = length;
48 int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
49 const unsigned char * data = (const unsigned char *)buffer;
51 CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
52 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
53 CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
55 while(data_to_read > 0){
56 rc = fortuna_add_entropy(data, block_sz, &prng);
57 rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
58 if(rc != SQLITE_OK){
59 break;
61 data_to_read -= block_sz;
62 data += block_sz;
63 block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
65 fortuna_ready(&prng);
67 CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
68 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
69 CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
71 return rc;
74 static int sqlcipher_ltc_activate(void *ctx) {
75 unsigned char random_buffer[FORTUNA_MAX_SZ];
77 CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
78 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
79 CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
81 sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
82 if(ltc_init == 0) {
83 if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR;
84 if(register_cipher(&rijndael_desc) < 0) return SQLITE_ERROR;
85 if(register_hash(&sha512_desc) < 0) return SQLITE_ERROR;
86 if(register_hash(&sha256_desc) < 0) return SQLITE_ERROR;
87 if(register_hash(&sha1_desc) < 0) return SQLITE_ERROR;
88 if(fortuna_start(&prng) != CRYPT_OK) {
89 return SQLITE_ERROR;
92 ltc_init = 1;
94 ltc_ref_count++;
96 #ifndef SQLCIPHER_TEST
97 sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
98 #endif
100 if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
101 return SQLITE_ERROR;
103 sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
105 CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
106 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
107 CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
109 return SQLITE_OK;
112 static int sqlcipher_ltc_deactivate(void *ctx) {
113 CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
114 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
115 CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
117 ltc_ref_count--;
118 if(ltc_ref_count == 0){
119 fortuna_done(&prng);
120 sqlcipher_memset((void *)&prng, 0, sizeof(prng));
123 CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
124 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
125 CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
127 return SQLITE_OK;
130 static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
131 return "libtomcrypt";
134 static const char* sqlcipher_ltc_get_provider_version(void *ctx) {
135 return SCRYPT;
138 static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
139 CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
140 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
141 CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
143 fortuna_read(buffer, length, &prng);
145 CODEC_TRACE_MUTEX("sqlcipher_ltc_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
146 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
147 CODEC_TRACE_MUTEX("sqlcipher_ltc_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
149 return SQLITE_OK;
152 static int sqlcipher_ltc_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) {
153 int rc, hash_idx;
154 hmac_state hmac;
155 unsigned long outlen;
156 switch(algorithm) {
157 case SQLCIPHER_HMAC_SHA1:
158 hash_idx = find_hash("sha1");
159 break;
160 case SQLCIPHER_HMAC_SHA256:
161 hash_idx = find_hash("sha256");
162 break;
163 case SQLCIPHER_HMAC_SHA512:
164 hash_idx = find_hash("sha512");
165 break;
166 default:
167 return SQLITE_ERROR;
170 if(hash_idx < 0) return SQLITE_ERROR;
171 outlen = hash_descriptor[hash_idx].hashsize;
173 if(in == NULL) return SQLITE_ERROR;
174 if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR;
175 if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR;
176 if(in2 != NULL && (rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR;
177 if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR;
178 return SQLITE_OK;
181 static int sqlcipher_ltc_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) {
182 int rc, hash_idx;
183 unsigned long outlen = key_sz;
185 switch(algorithm) {
186 case SQLCIPHER_HMAC_SHA1:
187 hash_idx = find_hash("sha1");
188 break;
189 case SQLCIPHER_HMAC_SHA256:
190 hash_idx = find_hash("sha256");
191 break;
192 case SQLCIPHER_HMAC_SHA512:
193 hash_idx = find_hash("sha512");
194 break;
195 default:
196 return SQLITE_ERROR;
198 if(hash_idx < 0) return SQLITE_ERROR;
200 if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
201 workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
202 return SQLITE_ERROR;
204 return SQLITE_OK;
207 static const char* sqlcipher_ltc_get_cipher(void *ctx) {
208 return "aes-256-cbc";
211 static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
212 int rc, cipher_idx;
213 symmetric_CBC cbc;
215 if((cipher_idx = find_cipher(LTC_CIPHER)) == -1) return SQLITE_ERROR;
216 if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR;
217 rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc);
218 if(rc != CRYPT_OK) return SQLITE_ERROR;
219 cbc_done(&cbc);
220 return SQLITE_OK;
223 static int sqlcipher_ltc_get_key_sz(void *ctx) {
224 int cipher_idx = find_cipher(LTC_CIPHER);
225 return cipher_descriptor[cipher_idx].max_key_length;
228 static int sqlcipher_ltc_get_iv_sz(void *ctx) {
229 int cipher_idx = find_cipher(LTC_CIPHER);
230 return cipher_descriptor[cipher_idx].block_length;
233 static int sqlcipher_ltc_get_block_sz(void *ctx) {
234 int cipher_idx = find_cipher(LTC_CIPHER);
235 return cipher_descriptor[cipher_idx].block_length;
238 static int sqlcipher_ltc_get_hmac_sz(void *ctx, int algorithm) {
239 int hash_idx;
240 switch(algorithm) {
241 case SQLCIPHER_HMAC_SHA1:
242 hash_idx = find_hash("sha1");
243 break;
244 case SQLCIPHER_HMAC_SHA256:
245 hash_idx = find_hash("sha256");
246 break;
247 case SQLCIPHER_HMAC_SHA512:
248 hash_idx = find_hash("sha512");
249 break;
250 default:
251 return 0;
254 if(hash_idx < 0) return 0;
256 return hash_descriptor[hash_idx].hashsize;
259 static int sqlcipher_ltc_ctx_init(void **ctx) {
260 sqlcipher_ltc_activate(NULL);
261 return SQLITE_OK;
264 static int sqlcipher_ltc_ctx_free(void **ctx) {
265 sqlcipher_ltc_deactivate(&ctx);
266 return SQLITE_OK;
269 static int sqlcipher_ltc_fips_status(void *ctx) {
270 return 0;
273 int sqlcipher_ltc_setup(sqlcipher_provider *p) {
274 p->activate = sqlcipher_ltc_activate;
275 p->deactivate = sqlcipher_ltc_deactivate;
276 p->get_provider_name = sqlcipher_ltc_get_provider_name;
277 p->random = sqlcipher_ltc_random;
278 p->hmac = sqlcipher_ltc_hmac;
279 p->kdf = sqlcipher_ltc_kdf;
280 p->cipher = sqlcipher_ltc_cipher;
281 p->get_cipher = sqlcipher_ltc_get_cipher;
282 p->get_key_sz = sqlcipher_ltc_get_key_sz;
283 p->get_iv_sz = sqlcipher_ltc_get_iv_sz;
284 p->get_block_sz = sqlcipher_ltc_get_block_sz;
285 p->get_hmac_sz = sqlcipher_ltc_get_hmac_sz;
286 p->ctx_init = sqlcipher_ltc_ctx_init;
287 p->ctx_free = sqlcipher_ltc_ctx_free;
288 p->add_random = sqlcipher_ltc_add_random;
289 p->fips_status = sqlcipher_ltc_fips_status;
290 p->get_provider_version = sqlcipher_ltc_get_provider_version;
291 return SQLITE_OK;
294 #endif
295 #endif
296 /* END SQLCIPHER */