|
| 1 | +#include <tomcrypt.h> |
| 2 | + |
| 3 | +void sqlcipher_activate(void *ctx) { |
| 4 | + register_prng(&fortuna_desc); |
| 5 | + register_cipher(&rijndael_desc); |
| 6 | + register_hash(&sha256_desc); |
| 7 | + register_hash(&sha1_desc); |
| 8 | +} |
| 9 | + |
| 10 | +void sqlcipher_deactivate(void *ctx) { |
| 11 | +} |
| 12 | + |
| 13 | +int sqlcipher_random(void *ctx, void *buffer, int length) { |
| 14 | + prng_state prng; |
| 15 | + int random_value; |
| 16 | + int random_buffer_sz = 256; |
| 17 | + char random_buffer[random_buffer_sz]; |
| 18 | + |
| 19 | + if(fortuna_start(&prng) != CRYPT_OK) return SQLITE_ERROR; |
| 20 | + sqlite3_randomness(sizeof(random_value), &random_value); |
| 21 | + sqlite3_snprintf(random_buffer_sz, random_buffer, "%d", random_value); |
| 22 | + if(fortuna_add_entropy(random_buffer, random_buffer_sz, &prng) != CRYPT_OK) return SQLITE_ERROR; |
| 23 | + if(fortuna_ready(&prng) != CRYPT_OK) return SQLITE_ERROR; |
| 24 | + fortuna_read(buffer, length, &prng); |
| 25 | + fortuna_done(&prng); |
| 26 | + return SQLITE_OK; |
| 27 | +} |
| 28 | + |
| 29 | +int sqlcipher_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) { |
| 30 | + int rc, hash_idx; |
| 31 | + hmac_state hmac; |
| 32 | + unsigned long outlen = key_sz; |
| 33 | + |
| 34 | + hash_idx = find_hash("sha1"); |
| 35 | + if((rc = hmac_init(&hmac, hash_idx, hmac_key, key_sz)) != CRYPT_OK) return SQLITE_ERROR; |
| 36 | + if((rc = hmac_process(&hmac, in, in_sz)) != CRYPT_OK) return SQLITE_ERROR; |
| 37 | + if((rc = hmac_process(&hmac, in2, in2_sz)) != CRYPT_OK) return SQLITE_ERROR; |
| 38 | + if((rc = hmac_done(&hmac, out, &outlen)) != CRYPT_OK) return SQLITE_ERROR; |
| 39 | + return SQLITE_OK; |
| 40 | +} |
| 41 | + |
| 42 | +int sqlcipher_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) { |
| 43 | + int rc, hash_idx; |
| 44 | + unsigned long outlen = key_sz; |
| 45 | + |
| 46 | + hash_idx = find_hash("sha1"); |
| 47 | + if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz, |
| 48 | + workfactor, hash_idx, key, &outlen)) != CRYPT_OK) return SQLITE_ERROR; |
| 49 | + return SQLITE_OK; |
| 50 | +} |
| 51 | + |
| 52 | +int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) { |
| 53 | + int rc, cipher_idx, hash_idx; |
| 54 | + symmetric_CBC cbc; |
| 55 | + |
| 56 | + if((cipher_idx = find_cipher(sqlcipher_get_cipher(ctx))) == -1) return SQLITE_ERROR; |
| 57 | + if((hash_idx = find_hash("sha256")) == -1) return SQLITE_ERROR; |
| 58 | + if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR; |
| 59 | + rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc); |
| 60 | + if(rc != CRYPT_OK) return SQLITE_ERROR; |
| 61 | + cbc_done(&cbc); |
| 62 | + return SQLITE_OK; |
| 63 | +} |
| 64 | + |
| 65 | +int sqlcipher_set_cipher(void *ctx, const char *cipher_name) { |
| 66 | + return SQLITE_OK; |
| 67 | +} |
| 68 | + |
| 69 | +const char* sqlcipher_get_cipher(void *ctx) { |
| 70 | + return "rijndael"; |
| 71 | +} |
| 72 | + |
| 73 | +int sqlcipher_get_key_sz(void *ctx) { |
| 74 | + int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx)); |
| 75 | + return cipher_descriptor[cipher_idx].max_key_length; |
| 76 | +} |
| 77 | + |
| 78 | +int sqlcipher_get_iv_sz(void *ctx) { |
| 79 | + int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx)); |
| 80 | + return cipher_descriptor[cipher_idx].block_length; |
| 81 | +} |
| 82 | + |
| 83 | +int sqlcipher_get_block_sz(void *ctx) { |
| 84 | + int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx)); |
| 85 | + return cipher_descriptor[cipher_idx].block_length; |
| 86 | +} |
| 87 | + |
| 88 | +int sqlcipher_get_hmac_sz(void *ctx) { |
| 89 | + int hash_idx = find_hash("sha1"); |
| 90 | + return hash_descriptor[hash_idx].hashsize; |
| 91 | +} |
| 92 | + |
| 93 | +int sqlcipher_ctx_copy(void *target_ctx, void *source_ctx) { |
| 94 | + return 1; |
| 95 | +} |
| 96 | + |
| 97 | +int sqlcipher_ctx_cmp(void *c1, void *c2) { |
| 98 | + return 1; |
| 99 | +} |
| 100 | + |
| 101 | +int sqlcipher_ctx_init(void **ctx) { |
| 102 | + return SQLITE_OK; |
| 103 | +} |
| 104 | + |
| 105 | +int sqlcipher_ctx_free(void **ctx) { |
| 106 | + return SQLITE_OK; |
| 107 | +} |
0 commit comments