PostgreSQL Source Code  git master
openssl.c
Go to the documentation of this file.
1 /*
2  * openssl.c
3  * Wrapper for OpenSSL library.
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/openssl.c
30  */
31 
32 #include "postgres.h"
33 
34 #include <openssl/evp.h>
35 #include <openssl/err.h>
36 #include <openssl/rand.h>
37 
38 #include "px.h"
39 #include "utils/memutils.h"
40 #include "utils/resowner.h"
41 
42 /*
43  * Max lengths we might want to handle.
44  */
45 #define MAX_KEY (512/8)
46 #define MAX_IV (128/8)
47 
48 /*
49  * Hashes
50  */
51 
52 /*
53  * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
54  * objects in a linked list, allocated in TopMemoryContext. We use the
55  * ResourceOwner mechanism to free them on abort.
56  */
57 typedef struct OSSLDigest
58 {
59  const EVP_MD *algo;
60  EVP_MD_CTX *ctx;
61 
63  struct OSSLDigest *next;
64  struct OSSLDigest *prev;
66 
67 static OSSLDigest *open_digests = NULL;
69 
70 static void
72 {
73  EVP_MD_CTX_destroy(digest->ctx);
74  if (digest->prev)
75  digest->prev->next = digest->next;
76  else
77  open_digests = digest->next;
78  if (digest->next)
79  digest->next->prev = digest->prev;
80  pfree(digest);
81 }
82 
83 /*
84  * Close any open OpenSSL handles on abort.
85  */
86 static void
88  bool isCommit,
89  bool isTopLevel,
90  void *arg)
91 {
92  OSSLDigest *curr;
94 
95  if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
96  return;
97 
99  while (next)
100  {
101  curr = next;
102  next = curr->next;
103 
104  if (curr->owner == CurrentResourceOwner)
105  {
106  if (isCommit)
107  elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
108  free_openssl_digest(curr);
109  }
110  }
111 }
112 
113 static unsigned
115 {
116  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
117  int result = EVP_MD_CTX_size(digest->ctx);
118 
119  if (result < 0)
120  elog(ERROR, "EVP_MD_CTX_size() failed");
121 
122  return result;
123 }
124 
125 static unsigned
127 {
128  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
129  int result = EVP_MD_CTX_block_size(digest->ctx);
130 
131  if (result < 0)
132  elog(ERROR, "EVP_MD_CTX_block_size() failed");
133 
134  return result;
135 }
136 
137 static void
139 {
140  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
141 
142  if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
143  elog(ERROR, "EVP_DigestInit_ex() failed");
144 }
145 
146 static void
147 digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
148 {
149  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
150 
151  if (!EVP_DigestUpdate(digest->ctx, data, dlen))
152  elog(ERROR, "EVP_DigestUpdate() failed");
153 }
154 
155 static void
157 {
158  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
159 
160  if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
161  elog(ERROR, "EVP_DigestFinal_ex() failed");
162 }
163 
164 static void
166 {
167  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
168 
169  free_openssl_digest(digest);
170  pfree(h);
171 }
172 
173 static int px_openssl_initialized = 0;
174 
175 /* PUBLIC functions */
176 
177 int
178 px_find_digest(const char *name, PX_MD **res)
179 {
180  const EVP_MD *md;
181  EVP_MD_CTX *ctx;
182  PX_MD *h;
183  OSSLDigest *digest;
184 
186  {
188  OpenSSL_add_all_algorithms();
189  }
190 
192  {
195  }
196 
197  md = EVP_get_digestbyname(name);
198  if (md == NULL)
199  return PXE_NO_HASH;
200 
201  /*
202  * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
203  * The order is crucial, to make sure we don't leak anything on
204  * out-of-memory or other error.
205  */
206  digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
207 
208  ctx = EVP_MD_CTX_create();
209  if (!ctx)
210  {
211  pfree(digest);
212  return PXE_CIPHER_INIT;
213  }
214  if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
215  {
216  EVP_MD_CTX_destroy(ctx);
217  pfree(digest);
218  return PXE_CIPHER_INIT;
219  }
220 
221  digest->algo = md;
222  digest->ctx = ctx;
223  digest->owner = CurrentResourceOwner;
224  digest->next = open_digests;
225  digest->prev = NULL;
226  open_digests = digest;
227 
228  /* The PX_MD object is allocated in the current memory context. */
229  h = palloc(sizeof(*h));
232  h->reset = digest_reset;
233  h->update = digest_update;
234  h->finish = digest_finish;
235  h->free = digest_free;
236  h->p.ptr = (void *) digest;
237 
238  *res = h;
239  return 0;
240 }
241 
242 /*
243  * Ciphers
244  *
245  * We use OpenSSL's EVP* family of functions for these.
246  */
247 
248 /*
249  * prototype for the EVP functions that return an algorithm, e.g.
250  * EVP_aes_128_cbc().
251  */
252 typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);
253 
254 /*
255  * ossl_cipher contains the static information about each cipher.
256  */
258 {
259  int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
263 };
264 
265 /*
266  * OSSLCipher contains the state for using a cipher. A separate OSSLCipher
267  * object is allocated in each px_find_cipher() call.
268  *
269  * To make sure we don't leak OpenSSL handles on abort, we keep OSSLCipher
270  * objects in a linked list, allocated in TopMemoryContext. We use the
271  * ResourceOwner mechanism to free them on abort.
272  */
273 typedef struct OSSLCipher
274 {
275  EVP_CIPHER_CTX *evp_ctx;
276  const EVP_CIPHER *evp_ciph;
279  unsigned klen;
280  unsigned init;
281  const struct ossl_cipher *ciph;
282 
284  struct OSSLCipher *next;
285  struct OSSLCipher *prev;
287 
288 static OSSLCipher *open_ciphers = NULL;
290 
291 static void
293 {
294  EVP_CIPHER_CTX_free(od->evp_ctx);
295  if (od->prev)
296  od->prev->next = od->next;
297  else
298  open_ciphers = od->next;
299  if (od->next)
300  od->next->prev = od->prev;
301  pfree(od);
302 }
303 
304 /*
305  * Close any open OpenSSL cipher handles on abort.
306  */
307 static void
309  bool isCommit,
310  bool isTopLevel,
311  void *arg)
312 {
313  OSSLCipher *curr;
314  OSSLCipher *next;
315 
316  if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
317  return;
318 
319  next = open_ciphers;
320  while (next)
321  {
322  curr = next;
323  next = curr->next;
324 
325  if (curr->owner == CurrentResourceOwner)
326  {
327  if (isCommit)
328  elog(WARNING, "pgcrypto cipher reference leak: cipher %p still referenced", curr);
329  free_openssl_cipher(curr);
330  }
331  }
332 }
333 
334 /* Common routines for all algorithms */
335 
336 static unsigned
338 {
339  OSSLCipher *od = (OSSLCipher *) c->ptr;
340 
341  return od->ciph->block_size;
342 }
343 
344 static unsigned
346 {
347  OSSLCipher *od = (OSSLCipher *) c->ptr;
348 
349  return od->ciph->max_key_size;
350 }
351 
352 static unsigned
354 {
355  unsigned ivlen;
356  OSSLCipher *od = (OSSLCipher *) c->ptr;
357 
358  ivlen = od->ciph->block_size;
359  return ivlen;
360 }
361 
362 static void
364 {
365  OSSLCipher *od = (OSSLCipher *) c->ptr;
366 
368  pfree(c);
369 }
370 
371 static int
372 gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
373  uint8 *res, unsigned *rlen)
374 {
375  OSSLCipher *od = c->ptr;
376  int outlen,
377  outlen2;
378 
379  if (!od->init)
380  {
381  if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
382  return PXE_CIPHER_INIT;
383  if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
384  return PXE_CIPHER_INIT;
385  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
386  return PXE_CIPHER_INIT;
387  if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
388  return PXE_CIPHER_INIT;
389  od->init = true;
390  }
391 
392  if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
393  return PXE_DECRYPT_FAILED;
394  if (!EVP_DecryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
395  return PXE_DECRYPT_FAILED;
396  *rlen = outlen + outlen2;
397 
398  return 0;
399 }
400 
401 static int
402 gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
403  uint8 *res, unsigned *rlen)
404 {
405  OSSLCipher *od = c->ptr;
406  int outlen,
407  outlen2;
408 
409  if (!od->init)
410  {
411  if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
412  return PXE_CIPHER_INIT;
413  if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
414  return PXE_CIPHER_INIT;
415  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
416  return PXE_CIPHER_INIT;
417  if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
418  return PXE_CIPHER_INIT;
419  od->init = true;
420  }
421 
422  if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
423  return PXE_ENCRYPT_FAILED;
424  if (!EVP_EncryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
425  return PXE_ENCRYPT_FAILED;
426  *rlen = outlen + outlen2;
427 
428  return 0;
429 }
430 
431 /* Blowfish */
432 
433 /*
434  * Check if strong crypto is supported. Some OpenSSL installations
435  * support only short keys and unfortunately BF_set_key does not return any
436  * error value. This function tests if is possible to use strong key.
437  */
438 static int
440 {
441  static const uint8 key[56] = {
442  0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
443  0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
444  0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
445  0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
446  0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
447  0xff, 0xff, 0xff, 0xff, 0xff, 0xff
448  };
449 
450  static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
451  static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
452  uint8 out[8];
453  EVP_CIPHER_CTX *evp_ctx;
454  int outlen;
455  int status = 0;
456 
457  /* encrypt with 448bits key and verify output */
458  evp_ctx = EVP_CIPHER_CTX_new();
459  if (!evp_ctx)
460  return 0;
461  if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))
462  goto leave;
463  if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))
464  goto leave;
465  if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL))
466  goto leave;
467 
468  if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8))
469  goto leave;
470 
471  if (memcmp(out, res, 8) != 0)
472  goto leave; /* Output does not match -> strong cipher is
473  * not supported */
474  status = 1;
475 
476 leave:
477  EVP_CIPHER_CTX_free(evp_ctx);
478  return status;
479 }
480 
481 static int
482 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
483 {
484  OSSLCipher *od = c->ptr;
485  unsigned bs = gen_ossl_block_size(c);
486  static int bf_is_strong = -1;
487 
488  /*
489  * Test if key len is supported. BF_set_key silently cut large keys and it
490  * could be a problem when user transfer crypted data from one server to
491  * another.
492  */
493 
494  if (bf_is_strong == -1)
495  bf_is_strong = bf_check_supported_key_len();
496 
497  if (!bf_is_strong && klen > 16)
498  return PXE_KEY_TOO_BIG;
499 
500  /* Key len is supported. We can use it. */
501  od->klen = klen;
502  memcpy(od->key, key, klen);
503 
504  if (iv)
505  memcpy(od->iv, iv, bs);
506  else
507  memset(od->iv, 0, bs);
508  return 0;
509 }
510 
511 /* DES */
512 
513 static int
514 ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
515 {
516  OSSLCipher *od = c->ptr;
517  unsigned bs = gen_ossl_block_size(c);
518 
519  od->klen = 8;
520  memset(od->key, 0, 8);
521  memcpy(od->key, key, klen > 8 ? 8 : klen);
522 
523  if (iv)
524  memcpy(od->iv, iv, bs);
525  else
526  memset(od->iv, 0, bs);
527  return 0;
528 }
529 
530 /* DES3 */
531 
532 static int
533 ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
534 {
535  OSSLCipher *od = c->ptr;
536  unsigned bs = gen_ossl_block_size(c);
537 
538  od->klen = 24;
539  memset(od->key, 0, 24);
540  memcpy(od->key, key, klen > 24 ? 24 : klen);
541 
542  if (iv)
543  memcpy(od->iv, iv, bs);
544  else
545  memset(od->iv, 0, bs);
546  return 0;
547 }
548 
549 /* CAST5 */
550 
551 static int
552 ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
553 {
554  OSSLCipher *od = c->ptr;
555  unsigned bs = gen_ossl_block_size(c);
556 
557  od->klen = klen;
558  memcpy(od->key, key, klen);
559 
560  if (iv)
561  memcpy(od->iv, iv, bs);
562  else
563  memset(od->iv, 0, bs);
564  return 0;
565 }
566 
567 /* AES */
568 
569 static int
570 ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
571 {
572  OSSLCipher *od = c->ptr;
573  unsigned bs = gen_ossl_block_size(c);
574 
575  if (klen <= 128 / 8)
576  od->klen = 128 / 8;
577  else if (klen <= 192 / 8)
578  od->klen = 192 / 8;
579  else if (klen <= 256 / 8)
580  od->klen = 256 / 8;
581  else
582  return PXE_KEY_TOO_BIG;
583 
584  memcpy(od->key, key, klen);
585 
586  if (iv)
587  memcpy(od->iv, iv, bs);
588  else
589  memset(od->iv, 0, bs);
590 
591  return 0;
592 }
593 
594 static int
595 ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
596 {
597  OSSLCipher *od = c->ptr;
598  int err;
599 
600  err = ossl_aes_init(c, key, klen, iv);
601  if (err)
602  return err;
603 
604  switch (od->klen)
605  {
606  case 128 / 8:
607  od->evp_ciph = EVP_aes_128_ecb();
608  break;
609  case 192 / 8:
610  od->evp_ciph = EVP_aes_192_ecb();
611  break;
612  case 256 / 8:
613  od->evp_ciph = EVP_aes_256_ecb();
614  break;
615  default:
616  /* shouldn't happen */
617  err = PXE_CIPHER_INIT;
618  break;
619  }
620 
621  return err;
622 }
623 
624 static int
625 ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
626 {
627  OSSLCipher *od = c->ptr;
628  int err;
629 
630  err = ossl_aes_init(c, key, klen, iv);
631  if (err)
632  return err;
633 
634  switch (od->klen)
635  {
636  case 128 / 8:
637  od->evp_ciph = EVP_aes_128_cbc();
638  break;
639  case 192 / 8:
640  od->evp_ciph = EVP_aes_192_cbc();
641  break;
642  case 256 / 8:
643  od->evp_ciph = EVP_aes_256_cbc();
644  break;
645  default:
646  /* shouldn't happen */
647  err = PXE_CIPHER_INIT;
648  break;
649  }
650 
651  return err;
652 }
653 
654 /*
655  * aliases
656  */
657 
658 static PX_Alias ossl_aliases[] = {
659  {"bf", "bf-cbc"},
660  {"blowfish", "bf-cbc"},
661  {"blowfish-cbc", "bf-cbc"},
662  {"blowfish-ecb", "bf-ecb"},
663  {"blowfish-cfb", "bf-cfb"},
664  {"des", "des-cbc"},
665  {"3des", "des3-cbc"},
666  {"3des-ecb", "des3-ecb"},
667  {"3des-cbc", "des3-cbc"},
668  {"cast5", "cast5-cbc"},
669  {"aes", "aes-cbc"},
670  {"rijndael", "aes-cbc"},
671  {"rijndael-cbc", "aes-cbc"},
672  {"rijndael-ecb", "aes-ecb"},
673  {NULL}
674 };
675 
676 static const struct ossl_cipher ossl_bf_cbc = {
677  bf_init,
678  EVP_bf_cbc,
679  64 / 8, 448 / 8
680 };
681 
682 static const struct ossl_cipher ossl_bf_ecb = {
683  bf_init,
684  EVP_bf_ecb,
685  64 / 8, 448 / 8
686 };
687 
688 static const struct ossl_cipher ossl_bf_cfb = {
689  bf_init,
690  EVP_bf_cfb,
691  64 / 8, 448 / 8
692 };
693 
694 static const struct ossl_cipher ossl_des_ecb = {
696  EVP_des_ecb,
697  64 / 8, 64 / 8
698 };
699 
700 static const struct ossl_cipher ossl_des_cbc = {
702  EVP_des_cbc,
703  64 / 8, 64 / 8
704 };
705 
706 static const struct ossl_cipher ossl_des3_ecb = {
708  EVP_des_ede3_ecb,
709  64 / 8, 192 / 8
710 };
711 
712 static const struct ossl_cipher ossl_des3_cbc = {
714  EVP_des_ede3_cbc,
715  64 / 8, 192 / 8
716 };
717 
718 static const struct ossl_cipher ossl_cast_ecb = {
720  EVP_cast5_ecb,
721  64 / 8, 128 / 8
722 };
723 
724 static const struct ossl_cipher ossl_cast_cbc = {
726  EVP_cast5_cbc,
727  64 / 8, 128 / 8
728 };
729 
730 static const struct ossl_cipher ossl_aes_ecb = {
732  NULL, /* EVP_aes_XXX_ecb(), determined in init
733  * function */
734  128 / 8, 256 / 8
735 };
736 
737 static const struct ossl_cipher ossl_aes_cbc = {
739  NULL, /* EVP_aes_XXX_cbc(), determined in init
740  * function */
741  128 / 8, 256 / 8
742 };
743 
744 /*
745  * Special handlers
746  */
748 {
749  const char *name;
750  const struct ossl_cipher *ciph;
751 };
752 
753 static const struct ossl_cipher_lookup ossl_cipher_types[] = {
754  {"bf-cbc", &ossl_bf_cbc},
755  {"bf-ecb", &ossl_bf_ecb},
756  {"bf-cfb", &ossl_bf_cfb},
757  {"des-ecb", &ossl_des_ecb},
758  {"des-cbc", &ossl_des_cbc},
759  {"des3-ecb", &ossl_des3_ecb},
760  {"des3-cbc", &ossl_des3_cbc},
761  {"cast5-ecb", &ossl_cast_ecb},
762  {"cast5-cbc", &ossl_cast_cbc},
763  {"aes-ecb", &ossl_aes_ecb},
764  {"aes-cbc", &ossl_aes_cbc},
765  {NULL}
766 };
767 
768 /* PUBLIC functions */
769 
770 int
772 {
773  const struct ossl_cipher_lookup *i;
774  PX_Cipher *c = NULL;
775  EVP_CIPHER_CTX *ctx;
776  OSSLCipher *od;
777 
779  for (i = ossl_cipher_types; i->name; i++)
780  if (strcmp(i->name, name) == 0)
781  break;
782  if (i->name == NULL)
783  return PXE_NO_CIPHER;
784 
786  {
789  }
790 
791  /*
792  * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
793  * The order is crucial, to make sure we don't leak anything on
794  * out-of-memory or other error.
795  */
796  od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
797  od->ciph = i->ciph;
798 
799  /* Allocate an EVP_CIPHER_CTX object. */
800  ctx = EVP_CIPHER_CTX_new();
801  if (!ctx)
802  {
803  pfree(od);
804  return PXE_CIPHER_INIT;
805  }
806 
807  od->evp_ctx = ctx;
809  od->next = open_ciphers;
810  od->prev = NULL;
811  open_ciphers = od;
812 
813  if (i->ciph->cipher_func)
814  od->evp_ciph = i->ciph->cipher_func();
815 
816  /* The PX_Cipher is allocated in current memory context */
817  c = palloc(sizeof(*c));
818  c->block_size = gen_ossl_block_size;
819  c->key_size = gen_ossl_key_size;
820  c->iv_size = gen_ossl_iv_size;
821  c->free = gen_ossl_free;
822  c->init = od->ciph->init;
823  c->encrypt = gen_ossl_encrypt;
824  c->decrypt = gen_ossl_decrypt;
825  c->ptr = od;
826 
827  *res = c;
828  return 0;
829 }
static int32 next
Definition: blutils.c:219
unsigned char uint8
Definition: c.h:439
#define WARNING
Definition: elog.h:30
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
const char * name
Definition: encode.c:561
int i
Definition: isn.c:73
void pfree(void *pointer)
Definition: mcxt.c:1175
MemoryContext TopMemoryContext
Definition: mcxt.c:48
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
void * palloc(Size size)
Definition: mcxt.c:1068
static bool cipher_resowner_callback_registered
Definition: openssl.c:289
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
int px_find_digest(const char *name, PX_MD **res)
Definition: openssl.c:178
static const struct ossl_cipher ossl_des_ecb
Definition: openssl.c:694
static bool digest_resowner_callback_registered
Definition: openssl.c:68
static void digest_free_callback(ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
Definition: openssl.c:87
const EVP_CIPHER *(* ossl_EVP_cipher_func)(void)
Definition: openssl.c:252
static const struct ossl_cipher ossl_des3_cbc
Definition: openssl.c:712
static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: openssl.c:147
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:482
static int bf_check_supported_key_len(void)
Definition: openssl.c:439
static unsigned digest_result_size(PX_MD *h)
Definition: openssl.c:114
static const struct ossl_cipher ossl_aes_ecb
Definition: openssl.c:730
#define MAX_KEY
Definition: openssl.c:45
static void digest_finish(PX_MD *h, uint8 *dst)
Definition: openssl.c:156
static OSSLCipher * open_ciphers
Definition: openssl.c:288
struct OSSLCipher OSSLCipher
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:292
static unsigned gen_ossl_key_size(PX_Cipher *c)
Definition: openssl.c:345
static int ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:595
static const struct ossl_cipher ossl_des3_ecb
Definition: openssl.c:706
static int px_openssl_initialized
Definition: openssl.c:173
static const struct ossl_cipher ossl_bf_cfb
Definition: openssl.c:688
struct OSSLDigest OSSLDigest
static int gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: openssl.c:402
static const struct ossl_cipher ossl_cast_cbc
Definition: openssl.c:724
static int gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: openssl.c:372
static void gen_ossl_free(PX_Cipher *c)
Definition: openssl.c:363
static const struct ossl_cipher ossl_des_cbc
Definition: openssl.c:700
static void digest_reset(PX_MD *h)
Definition: openssl.c:138
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:552
static unsigned gen_ossl_iv_size(PX_Cipher *c)
Definition: openssl.c:353
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: openssl.c:771
static const struct ossl_cipher ossl_bf_ecb
Definition: openssl.c:682
static PX_Alias ossl_aliases[]
Definition: openssl.c:658
static const struct ossl_cipher ossl_bf_cbc
Definition: openssl.c:676
static const struct ossl_cipher_lookup ossl_cipher_types[]
Definition: openssl.c:753
static void free_openssl_digest(OSSLDigest *digest)
Definition: openssl.c:71
#define MAX_IV
Definition: openssl.c:46
static const struct ossl_cipher ossl_cast_ecb
Definition: openssl.c:718
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:570
static void cipher_free_callback(ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
Definition: openssl.c:308
static unsigned digest_block_size(PX_MD *h)
Definition: openssl.c:126
static const struct ossl_cipher ossl_aes_cbc
Definition: openssl.c:737
static int ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:625
static void digest_free(PX_MD *h)
Definition: openssl.c:165
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:533
static OSSLDigest * open_digests
Definition: openssl.c:67
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:514
void * arg
const void * data
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
char * c
const char * px_resolve_alias(const PX_Alias *list, const char *name)
Definition: px.c:129
#define PXE_DECRYPT_FAILED
Definition: px.h:64
#define PXE_CIPHER_INIT
Definition: px.h:54
#define PXE_ENCRYPT_FAILED
Definition: px.h:65
#define PXE_NO_HASH
Definition: px.h:48
#define PXE_NO_CIPHER
Definition: px.h:49
#define PXE_KEY_TOO_BIG
Definition: px.h:53
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
Definition: resowner.c:849
ResourceReleasePhase
Definition: resowner.h:47
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:50
struct OSSLCipher * next
Definition: openssl.c:284
unsigned klen
Definition: openssl.c:279
const struct ossl_cipher * ciph
Definition: openssl.c:281
uint8 iv[MAX_IV]
Definition: openssl.c:278
struct OSSLCipher * prev
Definition: openssl.c:285
ResourceOwner owner
Definition: openssl.c:283
unsigned init
Definition: openssl.c:280
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:275
uint8 key[MAX_KEY]
Definition: openssl.c:277
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276
EVP_MD_CTX * ctx
Definition: openssl.c:60
struct OSSLDigest * next
Definition: openssl.c:63
const EVP_MD * algo
Definition: openssl.c:59
ResourceOwner owner
Definition: openssl.c:62
struct OSSLDigest * prev
Definition: openssl.c:64
const char * name
Definition: openssl.c:749
const struct ossl_cipher * ciph
Definition: openssl.c:750
int block_size
Definition: openssl.c:261
int max_key_size
Definition: openssl.c:262
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:259
ossl_EVP_cipher_func cipher_func
Definition: openssl.c:260
Definition: px.h:116
Definition: px.h:141
Definition: px.h:100
void(* free)(PX_MD *h)
Definition: px.h:106
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: px.h:104
unsigned(* result_size)(PX_MD *h)
Definition: px.h:101
union px_digest::@8 p
void(* reset)(PX_MD *h)
Definition: px.h:103
unsigned(* block_size)(PX_MD *h)
Definition: px.h:102
void * ptr
Definition: px.h:111
void(* finish)(PX_MD *h, uint8 *dst)
Definition: px.h:105