From 86376028f423aca324cc862815f3f4fd297bb74a Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Fri, 24 Apr 2009 15:45:40 -0400 Subject: [PATCH] use PKCS5_PBKDF2_HMAC_SHA1 for improved compatibility with more widely distributed openssl libraries --- src/crypto.c | 77 ++-------------------------------------------------- src/crypto.h | 11 +------- 2 files changed, 3 insertions(+), 85 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 4e542176..757b02b8 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -55,79 +55,6 @@ typedef struct { Btree *pBt; } codec_ctx; -/* - * The following two functions PKCS5_PBKDF2_HMAC_SHA256 and h__dump implement a - * PBKDF2 (rfc2898) variant using SHA 256 instead of SHA1. These functions were extracted directly from - * from openssl-0.9.8j crypto/evp/p5_crpt2.c. The only modifications have been to use a variable - * defined HMAC_HASH to allow selection of the message digest (instead of fixing it to EVP_sha1(). - * - Stephen -*/ - -#ifdef DEBUG_PKCS5V2 -static void h__dump (const unsigned char *p, int len) -{ - for (; len --; p++) fprintf(stderr, "%02X ", *p); - fprintf(stderr, "\n"); -} -#endif - - - /* This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2 using the only currently defined function HMAC - * with SHA1. Verified against test vectors posted by Peter Gutmann - * to the PKCS-TNG mailing list. - */ -static int PKCS5_PBKDF2_HMAC_SHA256(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - int keylen, unsigned char *out) -{ - unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4]; - int cplen, j, k, tkeylen; - unsigned long i = 1; - HMAC_CTX hctx; - - HMAC_CTX_init(&hctx); - p = out; - tkeylen = keylen; - if(!pass) passlen = 0; - else if(passlen == -1) passlen = strlen(pass); - while(tkeylen) { - if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH; - else cplen = tkeylen; - /* We are unlikely to ever use more than 256 blocks (5120 bits!) - * but just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - HMAC_Init_ex(&hctx, pass, passlen, HMAC_HASH, NULL); - HMAC_Update(&hctx, salt, saltlen); - HMAC_Update(&hctx, itmp, 4); - HMAC_Final(&hctx, digtmp, NULL); - memcpy(p, digtmp, cplen); - for(j = 1; j < iter; j++) { - HMAC(HMAC_HASH, pass, passlen, - digtmp, SHA_DIGEST_LENGTH, digtmp, NULL); - for(k = 0; k < cplen; k++) p[k] ^= digtmp[k]; - } - tkeylen-= cplen; - i++; - p+= cplen; - } - HMAC_CTX_cleanup(&hctx); -#ifdef DEBUG_PKCS5V2 - fprintf(stderr, "Password:\n"); - h__dump (pass, passlen); - fprintf(stderr, "Salt:\n"); - h__dump (salt, saltlen); - fprintf(stderr, "Iteration count %d\n", iter); - fprintf(stderr, "Key:\n"); - h__dump (out, keylen); -#endif - return 1; -} - static void codec_prepare_key(sqlite3 *db, const void *zKey, int nKey, void *salt, int nSalt, void *out, int *nOut) { /* if key data lenth is exactly 256 bits / 32 bytes use the data directly */ if (nKey == 67 && sqlite3StrNICmp(zKey ,"x'", 2) == 0) { @@ -141,8 +68,8 @@ static void codec_prepare_key(sqlite3 *db, const void *zKey, int nKey, void *sal sqlite3DbFree(db, key); /* otherwise the key is provided as a string so hash it to get key data */ } else { - *nOut = SHA_DIGEST_LENGTH; - PKCS5_PBKDF2_HMAC_SHA256(zKey, nKey, salt, nSalt, PBKDF2_ITER, SHA_DIGEST_LENGTH, out); + *nOut = KEY_LENGTH; + PKCS5_PBKDF2_HMAC_SHA1(zKey, nKey, salt, nSalt, PBKDF2_ITER, KEY_LENGTH, out); } } diff --git a/src/crypto.h b/src/crypto.h index 60513da0..d4aa5241 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -41,16 +41,7 @@ #define CIPHER_DECRYPT 0 #define CIPHER_ENCRYPT 1 -#define HMAC_HASH EVP_sha256() -#define SHA_DIGEST_LENGTH 32 - -#ifndef PBKDF2_SALT -#define PBKDF2_SALT {0x99, 0x76, 0x93, 0x7a, 0xc7, 0x2e, 0xd3, 0x88} -#endif - -#ifndef PBKDF2_SALT_SZ -#define PBKDF2_SALT_SZ 8 -#endif +#define KEY_LENGTH 32 #ifndef PBKDF2_ITER #define PBKDF2_ITER 4000