~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to contrib/pgcrypto/px-hmac.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * px-hmac.c
 
3
 *              HMAC implementation.
 
4
 *
 
5
 * Copyright (c) 2001 Marko Kreen
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *        notice, this list of conditions and the following disclaimer.
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *        notice, this list of conditions and the following disclaimer in the
 
15
 *        documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 * ARE DISCLAIMED.      IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
27
 * SUCH DAMAGE.
 
28
 *
 
29
 * contrib/pgcrypto/px-hmac.c
 
30
 */
 
31
 
 
32
#include "postgres.h"
 
33
 
 
34
#include "px.h"
 
35
 
 
36
#define HMAC_IPAD 0x36
 
37
#define HMAC_OPAD 0x5C
 
38
 
 
39
static unsigned
 
40
hmac_result_size(PX_HMAC *h)
 
41
{
 
42
        return px_md_result_size(h->md);
 
43
}
 
44
 
 
45
static unsigned
 
46
hmac_block_size(PX_HMAC *h)
 
47
{
 
48
        return px_md_block_size(h->md);
 
49
}
 
50
 
 
51
static void
 
52
hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
 
53
{
 
54
        unsigned        bs,
 
55
                                i;
 
56
        uint8      *keybuf;
 
57
        PX_MD      *md = h->md;
 
58
 
 
59
        bs = px_md_block_size(md);
 
60
        keybuf = px_alloc(bs);
 
61
        memset(keybuf, 0, bs);
 
62
 
 
63
        if (klen > bs)
 
64
        {
 
65
                px_md_update(md, key, klen);
 
66
                px_md_finish(md, keybuf);
 
67
                px_md_reset(md);
 
68
        }
 
69
        else
 
70
                memcpy(keybuf, key, klen);
 
71
 
 
72
        for (i = 0; i < bs; i++)
 
73
        {
 
74
                h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
 
75
                h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
 
76
        }
 
77
 
 
78
        memset(keybuf, 0, bs);
 
79
        px_free(keybuf);
 
80
 
 
81
        px_md_update(md, h->p.ipad, bs);
 
82
}
 
83
 
 
84
static void
 
85
hmac_reset(PX_HMAC *h)
 
86
{
 
87
        PX_MD      *md = h->md;
 
88
        unsigned        bs = px_md_block_size(md);
 
89
 
 
90
        px_md_reset(md);
 
91
        px_md_update(md, h->p.ipad, bs);
 
92
}
 
93
 
 
94
static void
 
95
hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen)
 
96
{
 
97
        px_md_update(h->md, data, dlen);
 
98
}
 
99
 
 
100
static void
 
101
hmac_finish(PX_HMAC *h, uint8 *dst)
 
102
{
 
103
        PX_MD      *md = h->md;
 
104
        unsigned        bs,
 
105
                                hlen;
 
106
        uint8      *buf;
 
107
 
 
108
        bs = px_md_block_size(md);
 
109
        hlen = px_md_result_size(md);
 
110
 
 
111
        buf = px_alloc(hlen);
 
112
 
 
113
        px_md_finish(md, buf);
 
114
 
 
115
        px_md_reset(md);
 
116
        px_md_update(md, h->p.opad, bs);
 
117
        px_md_update(md, buf, hlen);
 
118
        px_md_finish(md, dst);
 
119
 
 
120
        memset(buf, 0, hlen);
 
121
        px_free(buf);
 
122
}
 
123
 
 
124
static void
 
125
hmac_free(PX_HMAC *h)
 
126
{
 
127
        unsigned        bs;
 
128
 
 
129
        bs = px_md_block_size(h->md);
 
130
        px_md_free(h->md);
 
131
 
 
132
        memset(h->p.ipad, 0, bs);
 
133
        memset(h->p.opad, 0, bs);
 
134
        px_free(h->p.ipad);
 
135
        px_free(h->p.opad);
 
136
        px_free(h);
 
137
}
 
138
 
 
139
 
 
140
/* PUBLIC FUNCTIONS */
 
141
 
 
142
int
 
143
px_find_hmac(const char *name, PX_HMAC **res)
 
144
{
 
145
        int                     err;
 
146
        PX_MD      *md;
 
147
        PX_HMAC    *h;
 
148
        unsigned        bs;
 
149
 
 
150
        err = px_find_digest(name, &md);
 
151
        if (err)
 
152
                return err;
 
153
 
 
154
        bs = px_md_block_size(md);
 
155
        if (bs < 2)
 
156
        {
 
157
                px_md_free(md);
 
158
                return PXE_HASH_UNUSABLE_FOR_HMAC;
 
159
        }
 
160
 
 
161
        h = px_alloc(sizeof(*h));
 
162
        h->p.ipad = px_alloc(bs);
 
163
        h->p.opad = px_alloc(bs);
 
164
        h->md = md;
 
165
 
 
166
        h->result_size = hmac_result_size;
 
167
        h->block_size = hmac_block_size;
 
168
        h->reset = hmac_reset;
 
169
        h->update = hmac_update;
 
170
        h->finish = hmac_finish;
 
171
        h->free = hmac_free;
 
172
        h->init = hmac_init;
 
173
 
 
174
        *res = h;
 
175
 
 
176
        return 0;
 
177
}