00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "db_config.h"
00014
00015 #ifndef NO_SYSTEM_INCLUDES
00016 #include <string.h>
00017 #endif
00018
00019 #include "db_int.h"
00020 #include "dbinc/crypto.h"
00021 #include "dbinc/db_page.h"
00022 #include "dbinc/hash.h"
00023 #include "dbinc/hmac.h"
00024
00025 #define HMAC_OUTPUT_SIZE 20
00026 #define HMAC_BLOCK_SIZE 64
00027
00028 static void __db_hmac __P((u_int8_t *, u_int8_t *, size_t, u_int8_t *));
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 static void
00045 __db_hmac(k, data, data_len, mac)
00046 u_int8_t *k, *data, *mac;
00047 size_t data_len;
00048 {
00049 SHA1_CTX ctx;
00050 u_int8_t key[HMAC_BLOCK_SIZE];
00051 u_int8_t ipad[HMAC_BLOCK_SIZE];
00052 u_int8_t opad[HMAC_BLOCK_SIZE];
00053 u_int8_t tmp[HMAC_OUTPUT_SIZE];
00054 int i;
00055
00056 memset(key, 0x00, HMAC_BLOCK_SIZE);
00057 memset(ipad, 0x36, HMAC_BLOCK_SIZE);
00058 memset(opad, 0x5C, HMAC_BLOCK_SIZE);
00059
00060 memcpy(key, k, HMAC_OUTPUT_SIZE);
00061
00062 for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
00063 ipad[i] ^= key[i];
00064 opad[i] ^= key[i];
00065 }
00066
00067 __db_SHA1Init(&ctx);
00068 __db_SHA1Update(&ctx, ipad, HMAC_BLOCK_SIZE);
00069 __db_SHA1Update(&ctx, data, data_len);
00070 __db_SHA1Final(tmp, &ctx);
00071 __db_SHA1Init(&ctx);
00072 __db_SHA1Update(&ctx, opad, HMAC_BLOCK_SIZE);
00073 __db_SHA1Update(&ctx, tmp, HMAC_OUTPUT_SIZE);
00074 __db_SHA1Final(mac, &ctx);
00075 return;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 void
00085 __db_chksum(data, data_len, mac_key, store)
00086 u_int8_t *data;
00087 size_t data_len;
00088 u_int8_t *mac_key;
00089 u_int8_t *store;
00090 {
00091 int sumlen;
00092 u_int32_t hash4;
00093 u_int8_t tmp[DB_MAC_KEY];
00094
00095
00096
00097
00098
00099
00100
00101 if (mac_key == NULL)
00102 sumlen = sizeof(u_int32_t);
00103 else
00104 sumlen = DB_MAC_KEY;
00105 memset(store, 0, sumlen);
00106 if (mac_key == NULL) {
00107
00108 hash4 = __ham_func4(NULL, data, (u_int32_t)data_len);
00109 memcpy(store, &hash4, sumlen);
00110 } else {
00111 memset(tmp, 0, DB_MAC_KEY);
00112 __db_hmac(mac_key, data, data_len, tmp);
00113 memcpy(store, tmp, sumlen);
00114 }
00115 return;
00116 }
00117
00118
00119
00120
00121
00122
00123 void
00124 __db_derive_mac(passwd, plen, mac_key)
00125 u_int8_t *passwd;
00126 size_t plen;
00127 u_int8_t *mac_key;
00128 {
00129 SHA1_CTX ctx;
00130
00131
00132 __db_SHA1Init(&ctx);
00133 __db_SHA1Update(&ctx, passwd, plen);
00134 __db_SHA1Update(&ctx, (u_int8_t *)DB_MAC_MAGIC, strlen(DB_MAC_MAGIC));
00135 __db_SHA1Update(&ctx, passwd, plen);
00136 __db_SHA1Final(mac_key, &ctx);
00137
00138 return;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 int
00151 __db_check_chksum(dbenv, db_cipher, chksum, data, data_len, is_hmac)
00152 DB_ENV *dbenv;
00153 DB_CIPHER *db_cipher;
00154 u_int8_t *chksum;
00155 void *data;
00156 size_t data_len;
00157 int is_hmac;
00158 {
00159 int ret;
00160 size_t sum_len;
00161 u_int32_t hash4;
00162 u_int8_t *mac_key, old[DB_MAC_KEY], new[DB_MAC_KEY];
00163
00164
00165
00166
00167
00168
00169 if (is_hmac == 0) {
00170 if (db_cipher != NULL) {
00171 __db_err(dbenv,
00172 "Unencrypted checksum with a supplied encryption key");
00173 return (EINVAL);
00174 }
00175 sum_len = sizeof(u_int32_t);
00176 mac_key = NULL;
00177 } else {
00178 if (db_cipher == NULL) {
00179 __db_err(dbenv,
00180 "Encrypted checksum: no encryption key specified");
00181 return (EINVAL);
00182 }
00183 sum_len = DB_MAC_KEY;
00184 mac_key = db_cipher->mac_key;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 memcpy(old, chksum, sum_len);
00194 memset(chksum, 0, sum_len);
00195 if (mac_key == NULL) {
00196
00197 hash4 = __ham_func4(NULL, data, (u_int32_t)data_len);
00198 ret = memcmp((u_int32_t *)old, &hash4, sum_len) ? -1 : 0;
00199 } else {
00200 __db_hmac(mac_key, data, data_len, new);
00201 ret = memcmp(old, new, sum_len) ? -1 : 0;
00202 }
00203
00204 return (ret);
00205 }