~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/hmac/hmac.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*-
2
 
 * See the file LICENSE for redistribution information.
3
 
 *
4
 
 * Copyright (c) 2001-2002
5
 
 *      Sleepycat Software.  All rights reserved.
6
 
 *
7
 
 * Some parts of this code originally written by Adam Stubblefield,
8
 
 * astubble@rice.edu.
9
 
 */
10
 
 
11
 
#include "db_config.h"
12
 
 
13
 
#ifndef lint
14
 
static const char revid[] = "$Id$";
15
 
#endif /* not lint */
16
 
 
17
 
#ifndef NO_SYSTEM_INCLUDES
18
 
#include <string.h>
19
 
#endif
20
 
 
21
 
#include "db_int.h"
22
 
#include "dbinc/crypto.h"
23
 
#include "dbinc/db_page.h"      /* for hash.h only */
24
 
#include "dbinc/hash.h"
25
 
#include "dbinc/hmac.h"
26
 
 
27
 
#define HMAC_OUTPUT_SIZE        20
28
 
#define HMAC_BLOCK_SIZE 64
29
 
 
30
 
static void __db_hmac __P((u_int8_t *, u_int8_t *, size_t, u_int8_t *));
31
 
 
32
 
/*
33
 
 * !!!
34
 
 * All of these functions use a ctx structure on the stack.  The __db_SHA1Init
35
 
 * call does not initialize the 64-byte buffer portion of it.  The
36
 
 * underlying SHA1 functions will properly pad the buffer if the data length
37
 
 * is less than 64-bytes, so there isn't a chance of reading uninitialized
38
 
 * memory.  Although it would be cleaner to do a memset(ctx.buffer, 0, 64)
39
 
 * we do not want to incur that penalty if we don't have to for performance.
40
 
 */
41
 
 
42
 
/*
43
 
 * __db_hmac --
44
 
 *      Do a hashed MAC.
45
 
 */
46
 
static void
47
 
__db_hmac(k, data, data_len, mac)
48
 
        u_int8_t *k, *data, *mac;
49
 
        size_t data_len;
50
 
{
51
 
        SHA1_CTX ctx;
52
 
        u_int8_t key[HMAC_BLOCK_SIZE];
53
 
        u_int8_t ipad[HMAC_BLOCK_SIZE];
54
 
        u_int8_t opad[HMAC_BLOCK_SIZE];
55
 
        u_int8_t tmp[HMAC_OUTPUT_SIZE];
56
 
        int i;
57
 
 
58
 
        memset(key, 0x00, HMAC_BLOCK_SIZE);
59
 
        memset(ipad, 0x36, HMAC_BLOCK_SIZE);
60
 
        memset(opad, 0x5C, HMAC_BLOCK_SIZE);
61
 
 
62
 
        memcpy(key, k, HMAC_OUTPUT_SIZE);
63
 
 
64
 
        for (i = 0; i < HMAC_BLOCK_SIZE; i++) {
65
 
                ipad[i] ^= key[i];
66
 
                opad[i] ^= key[i];
67
 
        }
68
 
 
69
 
        __db_SHA1Init(&ctx);
70
 
        __db_SHA1Update(&ctx, ipad, HMAC_BLOCK_SIZE);
71
 
        __db_SHA1Update(&ctx, data, data_len);
72
 
        __db_SHA1Final(tmp, &ctx);
73
 
        __db_SHA1Init(&ctx);
74
 
        __db_SHA1Update(&ctx, opad, HMAC_BLOCK_SIZE);
75
 
        __db_SHA1Update(&ctx, tmp, HMAC_OUTPUT_SIZE);
76
 
        __db_SHA1Final(mac, &ctx);
77
 
        return;
78
 
}
79
 
 
80
 
/*
81
 
 * __db_chksum --
82
 
 *      Create a MAC/SHA1 checksum.
83
 
 *
84
 
 * PUBLIC: void __db_chksum __P((u_int8_t *, size_t, u_int8_t *, u_int8_t *));
85
 
 */
86
 
void
87
 
__db_chksum(data, data_len, mac_key, store)
88
 
        u_int8_t *data;
89
 
        size_t data_len;
90
 
        u_int8_t *mac_key;
91
 
        u_int8_t *store;
92
 
{
93
 
        int sumlen;
94
 
        u_int32_t hash4;
95
 
        u_int8_t tmp[DB_MAC_KEY];
96
 
 
97
 
        /*
98
 
         * Since the checksum might be on a page of data we are checksumming
99
 
         * we might be overwriting after checksumming, we zero-out the
100
 
         * checksum value so that we can have a known value there when
101
 
         * we verify the checksum.
102
 
         */
103
 
        if (mac_key == NULL)
104
 
                sumlen = sizeof(u_int32_t);
105
 
        else
106
 
                sumlen = DB_MAC_KEY;
107
 
        memset(store, 0, sumlen);
108
 
        if (mac_key == NULL) {
109
 
                /* Just a hash, no MAC */
110
 
                hash4 = __ham_func4(NULL, data, (u_int32_t)data_len);
111
 
                memcpy(store, &hash4, sumlen);
112
 
        } else {
113
 
                memset(tmp, 0, DB_MAC_KEY);
114
 
                __db_hmac(mac_key, data, data_len, tmp);
115
 
                memcpy(store, tmp, sumlen);
116
 
        }
117
 
        return;
118
 
}
119
 
/*
120
 
 * __db_derive_mac --
121
 
 *      Create a MAC/SHA1 key.
122
 
 *
123
 
 * PUBLIC: void __db_derive_mac __P((u_int8_t *, size_t, u_int8_t *));
124
 
 */
125
 
void
126
 
__db_derive_mac(passwd, plen, mac_key)
127
 
        u_int8_t *passwd;
128
 
        size_t plen;
129
 
        u_int8_t *mac_key;
130
 
{
131
 
        SHA1_CTX ctx;
132
 
 
133
 
        /* Compute the MAC key. mac_key must be 20 bytes. */
134
 
        __db_SHA1Init(&ctx);
135
 
        __db_SHA1Update(&ctx, passwd, plen);
136
 
        __db_SHA1Update(&ctx, (u_int8_t *)DB_MAC_MAGIC, strlen(DB_MAC_MAGIC));
137
 
        __db_SHA1Update(&ctx, passwd, plen);
138
 
        __db_SHA1Final(mac_key, &ctx);
139
 
 
140
 
        return;
141
 
}
142
 
 
143
 
/*
144
 
 * __db_check_chksum --
145
 
 *      Verify a checksum.
146
 
 *
147
 
 *      Return 0 on success, >0 (errno) on error, -1 on checksum mismatch.
148
 
 *
149
 
 * PUBLIC: int __db_check_chksum __P((DB_ENV *,
150
 
 * PUBLIC:     DB_CIPHER *, u_int8_t *, void *, size_t, int));
151
 
 */
152
 
int
153
 
__db_check_chksum(dbenv, db_cipher, chksum, data, data_len, is_hmac)
154
 
        DB_ENV *dbenv;
155
 
        DB_CIPHER *db_cipher;
156
 
        u_int8_t *chksum;
157
 
        void *data;
158
 
        size_t data_len;
159
 
        int is_hmac;
160
 
{
161
 
        int ret;
162
 
        size_t sum_len;
163
 
        u_int32_t hash4;
164
 
        u_int8_t *mac_key, old[DB_MAC_KEY], new[DB_MAC_KEY];
165
 
 
166
 
        /*
167
 
         * If we are just doing checksumming and not encryption, then checksum
168
 
         * is 4 bytes.  Otherwise, it is DB_MAC_KEY size.  Check for illegal
169
 
         * combinations of crypto/non-crypto checksums.
170
 
         */
171
 
        if (is_hmac == 0) {
172
 
                if (db_cipher != NULL) {
173
 
                        __db_err(dbenv,
174
 
    "Unencrypted checksum with a supplied encryption key");
175
 
                        return (EINVAL);
176
 
                }
177
 
                sum_len = sizeof(u_int32_t);
178
 
                mac_key = NULL;
179
 
        } else {
180
 
                if (db_cipher == NULL) {
181
 
                        __db_err(dbenv,
182
 
    "Encrypted checksum: no encryption key specified");
183
 
                        return (EINVAL);
184
 
                }
185
 
                sum_len = DB_MAC_KEY;
186
 
                mac_key = db_cipher->mac_key;
187
 
        }
188
 
 
189
 
        /*
190
 
         * !!!
191
 
         * Since the checksum might be on the page, we need to have known data
192
 
         * there so that we can generate the same original checksum.  We zero
193
 
         * it out, just like we do in __db_chksum above.
194
 
         */
195
 
        memcpy(old, chksum, sum_len);
196
 
        memset(chksum, 0, sum_len);
197
 
        if (mac_key == NULL) {
198
 
                /* Just a hash, no MAC */
199
 
                hash4 = __ham_func4(NULL, data, (u_int32_t)data_len);
200
 
                ret = memcmp((u_int32_t *)old, &hash4, sum_len) ? -1 : 0;
201
 
        } else {
202
 
                __db_hmac(mac_key, data, data_len, new);
203
 
                ret = memcmp(old, new, sum_len) ? -1 : 0;
204
 
        }
205
 
 
206
 
        return (ret);
207
 
}