PostgreSQL Source Code git master
hmac.h File Reference
Include dependency graph for hmac.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct pg_hmac_ctx pg_hmac_ctx
 

Functions

pg_hmac_ctxpg_hmac_create (pg_cryptohash_type type)
 
int pg_hmac_init (pg_hmac_ctx *ctx, const uint8 *key, size_t len)
 
int pg_hmac_update (pg_hmac_ctx *ctx, const uint8 *data, size_t len)
 
int pg_hmac_final (pg_hmac_ctx *ctx, uint8 *dest, size_t len)
 
void pg_hmac_free (pg_hmac_ctx *ctx)
 
const char * pg_hmac_error (pg_hmac_ctx *ctx)
 

Typedef Documentation

◆ pg_hmac_ctx

typedef struct pg_hmac_ctx pg_hmac_ctx

Definition at line 21 of file hmac.h.

Function Documentation

◆ pg_hmac_create()

pg_hmac_ctx * pg_hmac_create ( pg_cryptohash_type  type)

Definition at line 77 of file hmac.c.

78{
79 pg_hmac_ctx *ctx;
80
81 ctx = ALLOC(sizeof(pg_hmac_ctx));
82 if (ctx == NULL)
83 return NULL;
84 memset(ctx, 0, sizeof(pg_hmac_ctx));
85 ctx->type = type;
87 ctx->errreason = NULL;
88
89 /*
90 * Initialize the context data. This requires to know the digest and
91 * block lengths, that depend on the type of hash used.
92 */
93 switch (type)
94 {
95 case PG_MD5:
98 break;
99 case PG_SHA1:
102 break;
103 case PG_SHA224:
106 break;
107 case PG_SHA256:
110 break;
111 case PG_SHA384:
114 break;
115 case PG_SHA512:
118 break;
119 }
120
122 if (ctx->hash == NULL)
123 {
124 explicit_bzero(ctx, sizeof(pg_hmac_ctx));
125 FREE(ctx);
126 return NULL;
127 }
128
129 return ctx;
130}
pg_cryptohash_ctx * pg_cryptohash_create(pg_cryptohash_type type)
Definition: cryptohash.c:74
@ PG_SHA512
Definition: cryptohash.h:26
@ PG_SHA224
Definition: cryptohash.h:23
@ PG_SHA384
Definition: cryptohash.h:25
@ PG_SHA1
Definition: cryptohash.h:22
@ PG_SHA256
Definition: cryptohash.h:24
@ PG_MD5
Definition: cryptohash.h:21
#define FREE(ptr)
Definition: hmac.c:35
#define ALLOC(size)
Definition: hmac.c:34
@ PG_HMAC_ERROR_NONE
Definition: hmac.c:44
#define MD5_DIGEST_LENGTH
Definition: md5.h:20
#define MD5_BLOCK_SIZE
Definition: md5.h:22
void explicit_bzero(void *buf, size_t len)
#define SHA1_DIGEST_LENGTH
Definition: sha1.h:17
#define SHA1_BLOCK_SIZE
Definition: sha1.h:19
#define PG_SHA256_DIGEST_LENGTH
Definition: sha2.h:23
#define PG_SHA384_BLOCK_LENGTH
Definition: sha2.h:25
#define PG_SHA384_DIGEST_LENGTH
Definition: sha2.h:26
#define PG_SHA512_DIGEST_LENGTH
Definition: sha2.h:29
#define PG_SHA256_BLOCK_LENGTH
Definition: sha2.h:22
#define PG_SHA512_BLOCK_LENGTH
Definition: sha2.h:28
#define PG_SHA224_BLOCK_LENGTH
Definition: sha2.h:19
#define PG_SHA224_DIGEST_LENGTH
Definition: sha2.h:20
const char * errreason
Definition: hmac.c:55
pg_cryptohash_ctx * hash
Definition: hmac.c:52
int digest_size
Definition: hmac.c:57
int block_size
Definition: hmac.c:56
pg_cryptohash_type type
Definition: hmac.c:53
pg_hmac_errno error
Definition: hmac.c:54
const char * type

References ALLOC, pg_hmac_ctx::block_size, CurrentResourceOwner, pg_hmac_ctx::digest_size, ereport, errcode(), errmsg(), pg_hmac_ctx::error, ERROR, pg_hmac_ctx::errreason, explicit_bzero(), FREE, pg_hmac_ctx::hash, pg_hmac_ctx::hmacctx, MD5_BLOCK_SIZE, MD5_DIGEST_LENGTH, pg_cryptohash_create(), PG_HMAC_ERROR_NONE, PG_MD5, PG_SHA1, PG_SHA224, PG_SHA224_BLOCK_LENGTH, PG_SHA224_DIGEST_LENGTH, PG_SHA256, PG_SHA256_BLOCK_LENGTH, PG_SHA256_DIGEST_LENGTH, PG_SHA384, PG_SHA384_BLOCK_LENGTH, PG_SHA384_DIGEST_LENGTH, PG_SHA512, PG_SHA512_BLOCK_LENGTH, PG_SHA512_DIGEST_LENGTH, ResourceOwnerEnlarge(), ResourceOwnerRememberHMAC(), pg_hmac_ctx::resowner, SHA1_BLOCK_SIZE, SHA1_DIGEST_LENGTH, type, and pg_hmac_ctx::type.

Referenced by build_server_final_message(), calculate_client_proof(), scram_ClientKey(), scram_SaltedPassword(), scram_ServerKey(), verify_client_proof(), and verify_server_signature().

◆ pg_hmac_error()

const char * pg_hmac_error ( pg_hmac_ctx ctx)

Definition at line 306 of file hmac.c.

307{
308 if (ctx == NULL)
309 return _("out of memory");
310
311 /*
312 * If a reason is provided, rely on it, else fallback to any error code
313 * set.
314 */
315 if (ctx->errreason)
316 return ctx->errreason;
317
318 switch (ctx->error)
319 {
321 return _("success");
323 return _("internal error");
325 return _("out of memory");
326 }
327
328 Assert(false); /* cannot be reached */
329 return _("success");
330}
#define Assert(condition)
Definition: c.h:812
#define _(x)
Definition: elog.c:90
@ PG_HMAC_ERROR_INTERNAL
Definition: hmac.c:46
@ PG_HMAC_ERROR_OOM
Definition: hmac.c:45

References _, Assert, pg_hmac_ctx::error, pg_hmac_ctx::errreason, PG_HMAC_ERROR_DEST_LEN, PG_HMAC_ERROR_INTERNAL, PG_HMAC_ERROR_NONE, PG_HMAC_ERROR_OOM, and PG_HMAC_ERROR_OPENSSL.

Referenced by build_server_final_message(), calculate_client_proof(), scram_ClientKey(), scram_SaltedPassword(), scram_ServerKey(), verify_client_proof(), and verify_server_signature().

◆ pg_hmac_final()

int pg_hmac_final ( pg_hmac_ctx ctx,
uint8 dest,
size_t  len 
)

Definition at line 244 of file hmac.c.

245{
246 uint8 *h;
247
248 if (ctx == NULL)
249 return -1;
250
251 h = ALLOC(ctx->digest_size);
252 if (h == NULL)
253 {
255 return -1;
256 }
257 memset(h, 0, ctx->digest_size);
258
259 if (pg_cryptohash_final(ctx->hash, h, ctx->digest_size) < 0)
260 {
263 FREE(h);
264 return -1;
265 }
266
267 /* H(K XOR opad, tmp) */
268 if (pg_cryptohash_init(ctx->hash) < 0 ||
269 pg_cryptohash_update(ctx->hash, ctx->k_opad, ctx->block_size) < 0 ||
270 pg_cryptohash_update(ctx->hash, h, ctx->digest_size) < 0 ||
271 pg_cryptohash_final(ctx->hash, dest, len) < 0)
272 {
275 FREE(h);
276 return -1;
277 }
278
279 FREE(h);
280 return 0;
281}
uint8_t uint8
Definition: c.h:483
const char * pg_cryptohash_error(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:254
int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
Definition: cryptohash.c:136
int pg_cryptohash_init(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:100
int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
Definition: cryptohash.c:172
const void size_t len
uint8 k_opad[PG_SHA512_BLOCK_LENGTH]
Definition: hmac.c:64

References ALLOC, pg_hmac_ctx::block_size, generate_unaccent_rules::dest, pg_hmac_ctx::digest_size, pg_hmac_ctx::error, pg_hmac_ctx::errreason, FREE, pg_hmac_ctx::hash, pg_hmac_ctx::hmacctx, pg_hmac_ctx::k_opad, len, MD5_DIGEST_LENGTH, pg_cryptohash_error(), pg_cryptohash_final(), pg_cryptohash_init(), pg_cryptohash_update(), PG_HMAC_ERROR_DEST_LEN, PG_HMAC_ERROR_INTERNAL, PG_HMAC_ERROR_OOM, PG_HMAC_ERROR_OPENSSL, PG_MD5, PG_SHA1, PG_SHA224, PG_SHA224_DIGEST_LENGTH, PG_SHA256, PG_SHA256_DIGEST_LENGTH, PG_SHA384, PG_SHA384_DIGEST_LENGTH, PG_SHA512, PG_SHA512_DIGEST_LENGTH, SHA1_DIGEST_LENGTH, SSLerrmessage(), and pg_hmac_ctx::type.

Referenced by build_server_final_message(), calculate_client_proof(), scram_ClientKey(), scram_SaltedPassword(), scram_ServerKey(), verify_client_proof(), and verify_server_signature().

◆ pg_hmac_free()

void pg_hmac_free ( pg_hmac_ctx ctx)

◆ pg_hmac_init()

int pg_hmac_init ( pg_hmac_ctx ctx,
const uint8 key,
size_t  len 
)

Definition at line 138 of file hmac.c.

139{
140 int i;
141 int digest_size;
142 int block_size;
143 uint8 *shrinkbuf = NULL;
144
145 if (ctx == NULL)
146 return -1;
147
148 digest_size = ctx->digest_size;
149 block_size = ctx->block_size;
150
151 memset(ctx->k_opad, HMAC_OPAD, ctx->block_size);
152 memset(ctx->k_ipad, HMAC_IPAD, ctx->block_size);
153
154 /*
155 * If the key is longer than the block size, pass it through the hash once
156 * to shrink it down.
157 */
158 if (len > block_size)
159 {
160 pg_cryptohash_ctx *hash_ctx;
161
162 /* temporary buffer for one-time shrink */
163 shrinkbuf = ALLOC(digest_size);
164 if (shrinkbuf == NULL)
165 {
167 return -1;
168 }
169 memset(shrinkbuf, 0, digest_size);
170
171 hash_ctx = pg_cryptohash_create(ctx->type);
172 if (hash_ctx == NULL)
173 {
175 FREE(shrinkbuf);
176 return -1;
177 }
178
179 if (pg_cryptohash_init(hash_ctx) < 0 ||
180 pg_cryptohash_update(hash_ctx, key, len) < 0 ||
181 pg_cryptohash_final(hash_ctx, shrinkbuf, digest_size) < 0)
182 {
184 ctx->errreason = pg_cryptohash_error(hash_ctx);
185 pg_cryptohash_free(hash_ctx);
186 FREE(shrinkbuf);
187 return -1;
188 }
189
190 key = shrinkbuf;
191 len = digest_size;
192 pg_cryptohash_free(hash_ctx);
193 }
194
195 for (i = 0; i < len; i++)
196 {
197 ctx->k_ipad[i] ^= key[i];
198 ctx->k_opad[i] ^= key[i];
199 }
200
201 /* tmp = H(K XOR ipad, text) */
202 if (pg_cryptohash_init(ctx->hash) < 0 ||
203 pg_cryptohash_update(ctx->hash, ctx->k_ipad, ctx->block_size) < 0)
204 {
207 if (shrinkbuf)
208 FREE(shrinkbuf);
209 return -1;
210 }
211
212 if (shrinkbuf)
213 FREE(shrinkbuf);
214 return 0;
215}
static int block_size
Definition: guc_tables.c:596
#define HMAC_OPAD
Definition: hmac.c:68
#define HMAC_IPAD
Definition: hmac.c:67
int i
Definition: isn.c:72
uint8 k_ipad[PG_SHA512_BLOCK_LENGTH]
Definition: hmac.c:63

References ALLOC, block_size, pg_hmac_ctx::block_size, pg_hmac_ctx::digest_size, pg_hmac_ctx::error, pg_hmac_ctx::errreason, FREE, pg_hmac_ctx::hash, HMAC_IPAD, HMAC_OPAD, pg_hmac_ctx::hmacctx, i, pg_hmac_ctx::k_ipad, pg_hmac_ctx::k_opad, sort-test::key, len, pg_cryptohash_create(), pg_cryptohash_error(), pg_cryptohash_final(), pg_cryptohash_free(), pg_cryptohash_init(), pg_cryptohash_update(), PG_HMAC_ERROR_INTERNAL, PG_HMAC_ERROR_OOM, PG_HMAC_ERROR_OPENSSL, PG_MD5, PG_SHA1, PG_SHA224, PG_SHA256, PG_SHA384, PG_SHA512, SSLerrmessage(), and pg_hmac_ctx::type.

Referenced by build_server_final_message(), calculate_client_proof(), scram_ClientKey(), scram_SaltedPassword(), scram_ServerKey(), verify_client_proof(), and verify_server_signature().

◆ pg_hmac_update()

int pg_hmac_update ( pg_hmac_ctx ctx,
const uint8 data,
size_t  len 
)