diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-02-17 17:25:57 +0000 |
---|---|---|
committer | <> | 2015-03-17 16:26:24 +0000 |
commit | 780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch) | |
tree | 598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/crypto | |
parent | 7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff) | |
download | berkeleydb-master.tar.gz |
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/aes_method.c | 2 | ||||
-rw-r--r-- | src/crypto/crypto.c | 77 | ||||
-rw-r--r-- | src/crypto/mersenne/mt19937db.c | 2 | ||||
-rw-r--r-- | src/crypto/rijndael/rijndael-api-fst.c | 6 |
4 files changed, 69 insertions, 18 deletions
diff --git a/src/crypto/aes_method.c b/src/crypto/aes_method.c index 47193539..fed98f2b 100644 --- a/src/crypto/aes_method.c +++ b/src/crypto/aes_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved. * * Some parts of this code originally written by Adam Stubblefield, * -- astubble@rice.edu. diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index b731496f..ba115dd3 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved. * * Some parts of this code originally written by Adam Stubblefield * -- astubble@rice.edu @@ -15,6 +15,8 @@ #include "dbinc/db_page.h" #include "dbinc/crypto.h" +static void randomize __P((ENV *, void *, size_t)); + /* * __crypto_region_init -- * Initialize crypto. @@ -110,7 +112,7 @@ __crypto_region_init(env) * existing one, we are done with the passwd in the env. We smash * N-1 bytes so that we don't overwrite the nul. */ - memset(dbenv->passwd, 0xff, dbenv->passwd_len-1); + randomize(env, dbenv->passwd, dbenv->passwd_len - 1); __os_free(env, dbenv->passwd); dbenv->passwd = NULL; dbenv->passwd_len = 0; @@ -135,9 +137,10 @@ __crypto_env_close(env) dbenv = env->dbenv; if (dbenv->passwd != NULL) { - memset(dbenv->passwd, 0xff, dbenv->passwd_len-1); + randomize(env, dbenv->passwd, dbenv->passwd_len - 1); __os_free(env, dbenv->passwd); dbenv->passwd = NULL; + dbenv->passwd_len = 0; } if (!CRYPTO_ON(env)) @@ -225,7 +228,8 @@ __crypto_algsetup(env, db_cipher, alg, do_init) /* * __crypto_decrypt_meta -- - * Perform decryption on a metapage if needed. + * Perform decryption on a possible metadata page, if needed. This is used + * to help decide whether this is a real DB. Don't trust random data. * * PUBLIC: int __crypto_decrypt_meta __P((ENV *, DB *, u_int8_t *, int)); */ @@ -241,6 +245,7 @@ __crypto_decrypt_meta(env, dbp, mbuf, do_metachk) DB_CIPHER *db_cipher; size_t pg_off; int ret; + unsigned added_flags; u_int8_t *iv; /* @@ -293,6 +298,7 @@ __crypto_decrypt_meta(env, dbp, mbuf, do_metachk) */ if (meta->encrypt_alg != 0) { db_cipher = env->crypto_handle; + added_flags = 0; if (!F_ISSET(dbp, DB_AM_ENCRYPT)) { if (!CRYPTO_ON(env)) { __db_errx(env, DB_STR("0178", @@ -300,12 +306,14 @@ __crypto_decrypt_meta(env, dbp, mbuf, do_metachk) return (EINVAL); } /* - * User has a correct, secure env, but has encountered - * a database in that env that is secure, but user - * didn't dbp->set_flags. Since it is existing, use - * encryption if it is that way already. + * User has a correct, secure env and has encountered + * a database in that env that APPEARS TO BE secure, but + * user didn't set the encryption flags. Since the db + * already exists, turn encryption on. Remember what was + * set, so the flags can restored if it doesn't decrypt. */ - F_SET(dbp, DB_AM_ENCRYPT|DB_AM_CHKSUM); + added_flags = DB_AM_ENCRYPT | DB_AM_CHKSUM; + F_SET(dbp, added_flags); } /* * This was checked in set_flags when DB_AM_ENCRYPT was set. @@ -316,6 +324,7 @@ __crypto_decrypt_meta(env, dbp, mbuf, do_metachk) meta->encrypt_alg != db_cipher->alg) { __db_errx(env, DB_STR("0179", "Database encrypted using a different algorithm")); + F_CLR(dbp, added_flags); return (EINVAL); } DB_ASSERT(env, F_ISSET(dbp, DB_AM_CHKSUM)); @@ -334,12 +343,14 @@ alg_retry: if (!F_ISSET(db_cipher, CIPHER_ANY)) { if (do_metachk && (ret = db_cipher->decrypt(env, db_cipher->data, iv, mbuf + pg_off, - DBMETASIZE - pg_off))) + DBMETASIZE - pg_off))) { + F_CLR(dbp, added_flags); return (ret); - if (((BTMETA *)meta)->crypto_magic != - meta->magic) { + } + if (((BTMETA *)meta)->crypto_magic != meta->magic) { __db_errx(env, DB_STR("0180", "Invalid password")); + F_CLR(dbp, added_flags); return (EINVAL); } /* @@ -409,3 +420,45 @@ __crypto_set_passwd(env_src, env_dest) sh_passwd = R_ADDR(infop, cipher->passwd); return (__env_set_encrypt(env_dest->dbenv, sh_passwd, DB_ENCRYPT_AES)); } + +/* + * randomize + * + */ +static void +randomize(env, base, size) + ENV *env; + void *base; + size_t size; +{ + size_t i, copysize; + u_int8_t last, *p; + u_int32_t value; + + last = ((u_int8_t *)base)[size]; + for (i = 0, p = base; i < size; i += copysize, p += copysize) { + value = __os_random(); + if ((copysize = (size - i)) > sizeof(int32_t)) + copysize = sizeof(int32_t); + switch (copysize) + { + default: + memmove(p, &value, sizeof(int32_t)); + break; + case 3: + p[2] = (u_int8_t)(value >> 16); + /* FALLTHROUGH */ + case 2: + p[1] = (u_int8_t)(value >> 8); + /* FALLTHROUGH */ + case 1: + p[0] = (u_int8_t)(value); + break; + case 0: + DB_ASSERT(env, "randomize size 0?"); + break; + } + + } + DB_ASSERT(env, last == *p); +} diff --git a/src/crypto/mersenne/mt19937db.c b/src/crypto/mersenne/mt19937db.c index 2d53c312..0460b994 100644 --- a/src/crypto/mersenne/mt19937db.c +++ b/src/crypto/mersenne/mt19937db.c @@ -156,7 +156,7 @@ __db_genrand(env) * function will return 4 bytes if we don't send in a key. */ do { - __os_gettime(env, &ts, 1); + __os_gettime(env, &ts, 0); __db_chksum(NULL, (u_int8_t *)&ts.tv_sec, sizeof(ts.tv_sec), NULL, (u_int8_t *)&seed); } while (seed == 0); diff --git a/src/crypto/rijndael/rijndael-api-fst.c b/src/crypto/rijndael/rijndael-api-fst.c index 3fd6489d..5d67937c 100644 --- a/src/crypto/rijndael/rijndael-api-fst.c +++ b/src/crypto/rijndael/rijndael-api-fst.c @@ -56,7 +56,7 @@ __db_makeKey(key, direction, keyLen, keyMaterial) { u8 cipherKey[MAXKB]; - if (key == NULL) { + if (key == NULL || keyMaterial == NULL) { return BAD_KEY_INSTANCE; } @@ -72,9 +72,7 @@ __db_makeKey(key, direction, keyLen, keyMaterial) return BAD_KEY_MAT; } - if (keyMaterial != NULL) { - memcpy(cipherKey, keyMaterial, key->keyLen/8); - } + memcpy(cipherKey, keyMaterial, key->keyLen/8); if (direction == DIR_ENCRYPT) { key->Nr = __db_rijndaelKeySetupEnc(key->rk, cipherKey, keyLen); |