summaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-02-17 17:25:57 +0000
committer <>2015-03-17 16:26:24 +0000
commit780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch)
tree598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/crypto
parent7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff)
downloadberkeleydb-master.tar.gz
Imported from /home/lorry/working-area/delta_berkeleydb/db-6.1.23.tar.gz.HEADdb-6.1.23master
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/aes_method.c2
-rw-r--r--src/crypto/crypto.c77
-rw-r--r--src/crypto/mersenne/mt19937db.c2
-rw-r--r--src/crypto/rijndael/rijndael-api-fst.c6
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);