use PKCS5_PBKDF2_HMAC_SHA1 for improved compatibility with more widely distributed openssl libraries
This commit is contained in:
parent
276ad912c0
commit
86376028f4
77
src/crypto.c
77
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
|
||||
* <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
src/crypto.h
11
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user