PostgreSQL Source Code  git master
internal.c
Go to the documentation of this file.
1 /*
2  * internal.c
3  * Wrapper for builtin functions
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/internal.c
30  */
31 
32 #include "postgres.h"
33 
34 #include <time.h>
35 
36 #include "blf.h"
37 #include "px.h"
38 #include "rijndael.h"
39 
40 #include "common/cryptohash.h"
41 #include "common/md5.h"
42 #include "common/sha1.h"
43 
44 #define SHA1_BLOCK_SIZE 64
45 #define MD5_BLOCK_SIZE 64
46 
47 static void init_md5(PX_MD *h);
48 static void init_sha1(PX_MD *h);
49 
50 void init_sha224(PX_MD *h);
51 void init_sha256(PX_MD *h);
52 void init_sha384(PX_MD *h);
53 void init_sha512(PX_MD *h);
54 
55 struct int_digest
56 {
57  char *name;
58  void (*init) (PX_MD *h);
59 };
60 
61 static const struct int_digest
63  {"md5", init_md5},
64  {"sha1", init_sha1},
65  {"sha224", init_sha224},
66  {"sha256", init_sha256},
67  {"sha384", init_sha384},
68  {"sha512", init_sha512},
69  {NULL, NULL}
70 };
71 
72 /* MD5 */
73 
74 static unsigned
76 {
77  return MD5_DIGEST_LENGTH;
78 }
79 
80 static unsigned
82 {
83  return MD5_BLOCK_SIZE;
84 }
85 
86 static void
87 int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
88 {
90 
91  if (pg_cryptohash_update(ctx, data, dlen) < 0)
92  elog(ERROR, "could not update %s context", "MD5");
93 }
94 
95 static void
97 {
99 
100  if (pg_cryptohash_init(ctx) < 0)
101  elog(ERROR, "could not initialize %s context", "MD5");
102 }
103 
104 static void
106 {
108 
109  if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0)
110  elog(ERROR, "could not finalize %s context", "MD5");
111 }
112 
113 static void
115 {
117 
118  pg_cryptohash_free(ctx);
119  pfree(h);
120 }
121 
122 /* SHA1 */
123 
124 static unsigned
126 {
127  return SHA1_DIGEST_LENGTH;
128 }
129 
130 static unsigned
132 {
133  return SHA1_BLOCK_SIZE;
134 }
135 
136 static void
137 int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
138 {
140 
141  if (pg_cryptohash_update(ctx, data, dlen) < 0)
142  elog(ERROR, "could not update %s context", "SHA1");
143 }
144 
145 static void
147 {
149 
150  if (pg_cryptohash_init(ctx) < 0)
151  elog(ERROR, "could not initialize %s context", "SHA1");
152 }
153 
154 static void
156 {
158 
159  if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0)
160  elog(ERROR, "could not finalize %s context", "SHA1");
161 }
162 
163 static void
165 {
167 
168  pg_cryptohash_free(ctx);
169  pfree(h);
170 }
171 
172 /* init functions */
173 
174 static void
176 {
177  pg_cryptohash_ctx *ctx;
178 
180 
181  md->p.ptr = ctx;
182 
183  md->result_size = int_md5_len;
185  md->reset = int_md5_reset;
186  md->update = int_md5_update;
187  md->finish = int_md5_finish;
188  md->free = int_md5_free;
189 
190  md->reset(md);
191 }
192 
193 static void
195 {
196  pg_cryptohash_ctx *ctx;
197 
199 
200  md->p.ptr = ctx;
201 
204  md->reset = int_sha1_reset;
205  md->update = int_sha1_update;
206  md->finish = int_sha1_finish;
207  md->free = int_sha1_free;
208 
209  md->reset(md);
210 }
211 
212 /*
213  * ciphers generally
214  */
215 
216 #define INT_MAX_KEY (512/8)
217 #define INT_MAX_IV (128/8)
218 
219 struct int_ctx
220 {
223  union
224  {
227  } ctx;
228  unsigned keylen;
229  int is_init;
230  int mode;
231 };
232 
233 static void
235 {
236  struct int_ctx *cx = (struct int_ctx *) c->ptr;
237 
238  if (cx)
239  {
240  px_memset(cx, 0, sizeof *cx);
241  pfree(cx);
242  }
243  pfree(c);
244 }
245 
246 /*
247  * AES/rijndael
248  */
249 
250 #define MODE_ECB 0
251 #define MODE_CBC 1
252 
253 static unsigned
255 {
256  return 128 / 8;
257 }
258 
259 static unsigned
261 {
262  return 256 / 8;
263 }
264 
265 static unsigned
267 {
268  return 128 / 8;
269 }
270 
271 static int
272 rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
273 {
274  struct int_ctx *cx = (struct int_ctx *) c->ptr;
275 
276  if (klen <= 128 / 8)
277  cx->keylen = 128 / 8;
278  else if (klen <= 192 / 8)
279  cx->keylen = 192 / 8;
280  else if (klen <= 256 / 8)
281  cx->keylen = 256 / 8;
282  else
283  return PXE_KEY_TOO_BIG;
284 
285  memcpy(&cx->keybuf, key, klen);
286 
287  if (iv)
288  memcpy(cx->iv, iv, 128 / 8);
289 
290  return 0;
291 }
292 
293 static int
294 rj_real_init(struct int_ctx *cx, int dir)
295 {
296  aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
297  return 0;
298 }
299 
300 static int
301 rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
302 {
303  struct int_ctx *cx = (struct int_ctx *) c->ptr;
304 
305  if (!cx->is_init)
306  {
307  if (rj_real_init(cx, 1))
308  return PXE_CIPHER_INIT;
309  }
310 
311  if (dlen == 0)
312  return 0;
313 
314  if (dlen & 15)
315  return PXE_NOTBLOCKSIZE;
316 
317  memcpy(res, data, dlen);
318 
319  if (cx->mode == MODE_CBC)
320  {
321  aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
322  memcpy(cx->iv, res + dlen - 16, 16);
323  }
324  else
325  aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
326 
327  return 0;
328 }
329 
330 static int
331 rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
332 {
333  struct int_ctx *cx = (struct int_ctx *) c->ptr;
334 
335  if (!cx->is_init)
336  if (rj_real_init(cx, 0))
337  return PXE_CIPHER_INIT;
338 
339  if (dlen == 0)
340  return 0;
341 
342  if (dlen & 15)
343  return PXE_NOTBLOCKSIZE;
344 
345  memcpy(res, data, dlen);
346 
347  if (cx->mode == MODE_CBC)
348  {
349  aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
350  memcpy(cx->iv, data + dlen - 16, 16);
351  }
352  else
353  aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
354 
355  return 0;
356 }
357 
358 /*
359  * initializers
360  */
361 
362 static PX_Cipher *
364 {
365  PX_Cipher *c;
366  struct int_ctx *cx;
367 
368  c = palloc0(sizeof *c);
369 
371  c->key_size = rj_key_size;
372  c->iv_size = rj_iv_size;
373  c->init = rj_init;
374  c->encrypt = rj_encrypt;
375  c->decrypt = rj_decrypt;
376  c->free = intctx_free;
377 
378  cx = palloc0(sizeof *cx);
379  cx->mode = mode;
380 
381  c->ptr = cx;
382  return c;
383 }
384 
385 /*
386  * blowfish
387  */
388 
389 static unsigned
391 {
392  return 8;
393 }
394 
395 static unsigned
397 {
398  return 448 / 8;
399 }
400 
401 static unsigned
403 {
404  return 8;
405 }
406 
407 static int
408 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
409 {
410  struct int_ctx *cx = (struct int_ctx *) c->ptr;
411 
412  blowfish_setkey(&cx->ctx.bf, key, klen);
413  if (iv)
414  blowfish_setiv(&cx->ctx.bf, iv);
415 
416  return 0;
417 }
418 
419 static int
420 bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
421 {
422  struct int_ctx *cx = (struct int_ctx *) c->ptr;
423  BlowfishContext *bfctx = &cx->ctx.bf;
424 
425  if (dlen == 0)
426  return 0;
427 
428  if (dlen & 7)
429  return PXE_NOTBLOCKSIZE;
430 
431  memcpy(res, data, dlen);
432  switch (cx->mode)
433  {
434  case MODE_ECB:
435  blowfish_encrypt_ecb(res, dlen, bfctx);
436  break;
437  case MODE_CBC:
438  blowfish_encrypt_cbc(res, dlen, bfctx);
439  break;
440  }
441  return 0;
442 }
443 
444 static int
445 bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
446 {
447  struct int_ctx *cx = (struct int_ctx *) c->ptr;
448  BlowfishContext *bfctx = &cx->ctx.bf;
449 
450  if (dlen == 0)
451  return 0;
452 
453  if (dlen & 7)
454  return PXE_NOTBLOCKSIZE;
455 
456  memcpy(res, data, dlen);
457  switch (cx->mode)
458  {
459  case MODE_ECB:
460  blowfish_decrypt_ecb(res, dlen, bfctx);
461  break;
462  case MODE_CBC:
463  blowfish_decrypt_cbc(res, dlen, bfctx);
464  break;
465  }
466  return 0;
467 }
468 
469 static PX_Cipher *
471 {
472  PX_Cipher *c;
473  struct int_ctx *cx;
474 
475  c = palloc0(sizeof *c);
476 
478  c->key_size = bf_key_size;
479  c->iv_size = bf_iv_size;
480  c->init = bf_init;
481  c->encrypt = bf_encrypt;
482  c->decrypt = bf_decrypt;
483  c->free = intctx_free;
484 
485  cx = palloc0(sizeof *cx);
486  cx->mode = mode;
487  c->ptr = cx;
488  return c;
489 }
490 
491 /* ciphers */
492 
493 static PX_Cipher *
495 {
496  return rj_load(MODE_ECB);
497 }
498 
499 static PX_Cipher *
501 {
502  return rj_load(MODE_CBC);
503 }
504 
505 static PX_Cipher *
507 {
508  return bf_load(MODE_ECB);
509 }
510 
511 static PX_Cipher *
513 {
514  return bf_load(MODE_CBC);
515 }
516 
518 {
519  char *name;
520  PX_Cipher *(*load) (void);
521 };
522 
523 static const struct int_cipher
525  {"bf-cbc", bf_cbc_load},
526  {"bf-ecb", bf_ecb_load},
527  {"aes-128-cbc", rj_128_cbc},
528  {"aes-128-ecb", rj_128_ecb},
529  {NULL, NULL}
530 };
531 
532 static const PX_Alias int_aliases[] = {
533  {"bf", "bf-cbc"},
534  {"blowfish", "bf-cbc"},
535  {"aes", "aes-128-cbc"},
536  {"aes-ecb", "aes-128-ecb"},
537  {"aes-cbc", "aes-128-cbc"},
538  {"aes-128", "aes-128-cbc"},
539  {"rijndael", "aes-128-cbc"},
540  {"rijndael-128", "aes-128-cbc"},
541  {NULL, NULL}
542 };
543 
544 /* PUBLIC FUNCTIONS */
545 
546 int
547 px_find_digest(const char *name, PX_MD **res)
548 {
549  const struct int_digest *p;
550  PX_MD *h;
551 
552  for (p = int_digest_list; p->name; p++)
553  if (pg_strcasecmp(p->name, name) == 0)
554  {
555  h = palloc(sizeof(*h));
556  p->init(h);
557 
558  *res = h;
559 
560  return 0;
561  }
562  return PXE_NO_HASH;
563 }
564 
565 int
566 px_find_cipher(const char *name, PX_Cipher **res)
567 {
568  int i;
569  PX_Cipher *c = NULL;
570 
571  name = px_resolve_alias(int_aliases, name);
572 
573  for (i = 0; int_ciphers[i].name; i++)
574  if (strcmp(int_ciphers[i].name, name) == 0)
575  {
576  c = int_ciphers[i].load();
577  break;
578  }
579 
580  if (c == NULL)
581  return PXE_NO_CIPHER;
582 
583  *res = c;
584  return 0;
585 }
int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
Definition: cryptohash.c:168
static const struct int_cipher int_ciphers[]
Definition: internal.c:524
static PgChecksumMode mode
Definition: pg_checksums.c:65
void aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
Definition: rijndael.c:545
void * ptr
Definition: px.h:110
void init_sha384(PX_MD *h)
#define MD5_BLOCK_SIZE
Definition: internal.c:45
PX_Cipher *(* load)(void)
Definition: internal.c:520
static PX_Cipher * bf_cbc_load(void)
Definition: internal.c:512
#define INT_MAX_KEY
Definition: internal.c:216
static int bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: internal.c:445
static PX_Cipher * bf_ecb_load(void)
Definition: internal.c:506
void(* free)(PX_MD *h)
Definition: px.h:105
static const struct int_digest int_digest_list[]
Definition: internal.c:62
static void intctx_free(PX_Cipher *c)
Definition: internal.c:234
union int_ctx::@0 ctx
BlowfishContext bf
Definition: internal.c:225
#define SHA1_DIGEST_LENGTH
Definition: sha1.h:17
static unsigned int_sha1_block_len(PX_MD *h)
Definition: internal.c:131
char * name
Definition: internal.c:519
static PX_Cipher * bf_load(int mode)
Definition: internal.c:470
unsigned(* block_size)(PX_Cipher *c)
Definition: px.h:141
unsigned char uint8
Definition: c.h:439
void aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
Definition: rijndael.c:567
void blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
Definition: blf.c:321
int(* decrypt)(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: px.h:147
const char * px_resolve_alias(const PX_Alias *list, const char *name)
Definition: px.c:133
void * ptr
Definition: px.h:150
uint8 keybuf[INT_MAX_KEY]
Definition: internal.c:221
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define MODE_CBC
Definition: internal.c:251
void(* free)(PX_Cipher *c)
Definition: px.h:148
Definition: px.h:114
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
static void int_sha1_free(PX_MD *h)
Definition: internal.c:164
static void int_md5_reset(PX_MD *h)
Definition: internal.c:96
#define SHA1_BLOCK_SIZE
Definition: internal.c:44
void aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc)
Definition: rijndael.c:504
static unsigned rj_block_size(PX_Cipher *c)
Definition: internal.c:254
void pfree(void *pointer)
Definition: mcxt.c:1169
int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
void blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
Definition: blf.c:408
unsigned(* block_size)(PX_MD *h)
Definition: px.h:101
static int rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: internal.c:301
static void int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: internal.c:137
#define ERROR
Definition: elog.h:46
void aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
Definition: rijndael.c:529
union px_digest::@9 p
Definition: px.h:98
static int rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: internal.c:272
#define MD5_DIGEST_LENGTH
Definition: md5.h:20
#define PXE_NO_HASH
Definition: px.h:48
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: px.h:103
static unsigned rj_key_size(PX_Cipher *c)
Definition: internal.c:260
void(* finish)(PX_MD *h, uint8 *dst)
Definition: px.h:104
unsigned(* iv_size)(PX_Cipher *c)
Definition: px.h:143
void blowfish_setiv(BlowfishContext *ctx, const uint8 *iv)
Definition: blf.c:495
char * c
void init_sha224(PX_MD *h)
static void init_md5(PX_MD *h)
Definition: internal.c:175
static unsigned int_md5_len(PX_MD *h)
Definition: internal.c:75
static unsigned int_sha1_len(PX_MD *h)
Definition: internal.c:125
unsigned(* key_size)(PX_Cipher *c)
Definition: px.h:142
void init_sha256(PX_MD *h)
static unsigned rj_iv_size(PX_Cipher *c)
Definition: internal.c:266
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: internal.c:408
#define INT_MAX_IV
Definition: internal.c:217
int(* encrypt)(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: px.h:146
unsigned(* result_size)(PX_MD *h)
Definition: px.h:100
static void int_md5_finish(PX_MD *h, uint8 *dst)
Definition: internal.c:105
static int rj_real_init(struct int_ctx *cx, int dir)
Definition: internal.c:294
static unsigned int_md5_block_len(PX_MD *h)
Definition: internal.c:81
void blowfish_setkey(BlowfishContext *ctx, const uint8 *key, short keybytes)
Definition: blf.c:429
void * palloc0(Size size)
Definition: mcxt.c:1093
char * name
Definition: internal.c:57
static unsigned bf_key_size(PX_Cipher *c)
Definition: internal.c:396
static int bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: internal.c:420
#define PXE_KEY_TOO_BIG
Definition: px.h:53
void init_sha512(PX_MD *h)
#define PXE_CIPHER_INIT
Definition: px.h:54
pg_cryptohash_ctx * pg_cryptohash_create(pg_cryptohash_type type)
Definition: cryptohash.c:66
void(* reset)(PX_MD *h)
Definition: px.h:102
static int rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: internal.c:331
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: px.h:145
int pg_cryptohash_init(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:92
unsigned keylen
Definition: internal.c:228
void aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
Definition: rijndael.c:513
#define MODE_ECB
Definition: internal.c:250
#define PXE_NOTBLOCKSIZE
Definition: px.h:50
Definition: px.h:139
void blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
Definition: blf.c:387
rijndael_ctx rj
Definition: internal.c:226
static unsigned bf_block_size(PX_Cipher *c)
Definition: internal.c:390
int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
Definition: cryptohash.c:130
static void int_sha1_reset(PX_MD *h)
Definition: internal.c:146
void * palloc(Size size)
Definition: mcxt.c:1062
static PX_Cipher * rj_128_ecb(void)
Definition: internal.c:494
#define elog(elevel,...)
Definition: elog.h:232
int i
static void int_sha1_finish(PX_MD *h, uint8 *dst)
Definition: internal.c:155
static PX_Cipher * rj_load(int mode)
Definition: internal.c:363
#define PXE_NO_CIPHER
Definition: px.h:49
void blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
Definition: blf.c:354
static void init_sha1(PX_MD *h)
Definition: internal.c:194
static unsigned bf_iv_size(PX_Cipher *c)
Definition: internal.c:402
static PX_Cipher * rj_128_cbc(void)
Definition: internal.c:500
static const PX_Alias int_aliases[]
Definition: internal.c:532
int mode
Definition: internal.c:230
void(* init)(PX_MD *h)
Definition: internal.c:58
static void int_md5_free(PX_MD *h)
Definition: internal.c:114
void pg_cryptohash_free(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:216
int px_find_digest(const char *name, PX_MD **res)
Definition: internal.c:547
void px_memset(void *ptr, int c, size_t len)
Definition: px.c:127
static void int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: internal.c:87
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: internal.c:566
int is_init
Definition: internal.c:229