Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "postgres.h"
00033
00034 #include "px.h"
00035
00036 #define HMAC_IPAD 0x36
00037 #define HMAC_OPAD 0x5C
00038
00039 static unsigned
00040 hmac_result_size(PX_HMAC *h)
00041 {
00042 return px_md_result_size(h->md);
00043 }
00044
00045 static unsigned
00046 hmac_block_size(PX_HMAC *h)
00047 {
00048 return px_md_block_size(h->md);
00049 }
00050
00051 static void
00052 hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
00053 {
00054 unsigned bs,
00055 i;
00056 uint8 *keybuf;
00057 PX_MD *md = h->md;
00058
00059 bs = px_md_block_size(md);
00060 keybuf = px_alloc(bs);
00061 memset(keybuf, 0, bs);
00062
00063 if (klen > bs)
00064 {
00065 px_md_update(md, key, klen);
00066 px_md_finish(md, keybuf);
00067 px_md_reset(md);
00068 }
00069 else
00070 memcpy(keybuf, key, klen);
00071
00072 for (i = 0; i < bs; i++)
00073 {
00074 h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
00075 h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
00076 }
00077
00078 memset(keybuf, 0, bs);
00079 px_free(keybuf);
00080
00081 px_md_update(md, h->p.ipad, bs);
00082 }
00083
00084 static void
00085 hmac_reset(PX_HMAC *h)
00086 {
00087 PX_MD *md = h->md;
00088 unsigned bs = px_md_block_size(md);
00089
00090 px_md_reset(md);
00091 px_md_update(md, h->p.ipad, bs);
00092 }
00093
00094 static void
00095 hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen)
00096 {
00097 px_md_update(h->md, data, dlen);
00098 }
00099
00100 static void
00101 hmac_finish(PX_HMAC *h, uint8 *dst)
00102 {
00103 PX_MD *md = h->md;
00104 unsigned bs,
00105 hlen;
00106 uint8 *buf;
00107
00108 bs = px_md_block_size(md);
00109 hlen = px_md_result_size(md);
00110
00111 buf = px_alloc(hlen);
00112
00113 px_md_finish(md, buf);
00114
00115 px_md_reset(md);
00116 px_md_update(md, h->p.opad, bs);
00117 px_md_update(md, buf, hlen);
00118 px_md_finish(md, dst);
00119
00120 memset(buf, 0, hlen);
00121 px_free(buf);
00122 }
00123
00124 static void
00125 hmac_free(PX_HMAC *h)
00126 {
00127 unsigned bs;
00128
00129 bs = px_md_block_size(h->md);
00130 px_md_free(h->md);
00131
00132 memset(h->p.ipad, 0, bs);
00133 memset(h->p.opad, 0, bs);
00134 px_free(h->p.ipad);
00135 px_free(h->p.opad);
00136 px_free(h);
00137 }
00138
00139
00140
00141
00142 int
00143 px_find_hmac(const char *name, PX_HMAC **res)
00144 {
00145 int err;
00146 PX_MD *md;
00147 PX_HMAC *h;
00148 unsigned bs;
00149
00150 err = px_find_digest(name, &md);
00151 if (err)
00152 return err;
00153
00154 bs = px_md_block_size(md);
00155 if (bs < 2)
00156 {
00157 px_md_free(md);
00158 return PXE_HASH_UNUSABLE_FOR_HMAC;
00159 }
00160
00161 h = px_alloc(sizeof(*h));
00162 h->p.ipad = px_alloc(bs);
00163 h->p.opad = px_alloc(bs);
00164 h->md = md;
00165
00166 h->result_size = hmac_result_size;
00167 h->block_size = hmac_block_size;
00168 h->reset = hmac_reset;
00169 h->update = hmac_update;
00170 h->finish = hmac_finish;
00171 h->free = hmac_free;
00172 h->init = hmac_init;
00173
00174 *res = h;
00175
00176 return 0;
00177 }