PostgreSQL Source Code  git master
openssl.c File Reference
#include "postgres.h"
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include "px.h"
#include "utils/memutils.h"
#include "utils/resowner.h"
Include dependency graph for openssl.c:

Go to the source code of this file.

Data Structures

struct  OSSLDigest
 
struct  ossl_cipher
 
struct  OSSLCipher
 
struct  ossl_cipher_lookup
 

Macros

#define MAX_KEY   (512/8)
 
#define MAX_IV   (128/8)
 

Typedefs

typedef struct OSSLDigest OSSLDigest
 
typedef const EVP_CIPHER *(* ossl_EVP_cipher_func) (void)
 
typedef struct OSSLCipher OSSLCipher
 

Functions

static void free_openssl_digest (OSSLDigest *digest)
 
static void digest_free_callback (ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
 
static unsigned digest_result_size (PX_MD *h)
 
static unsigned digest_block_size (PX_MD *h)
 
static void digest_reset (PX_MD *h)
 
static void digest_update (PX_MD *h, const uint8 *data, unsigned dlen)
 
static void digest_finish (PX_MD *h, uint8 *dst)
 
static void digest_free (PX_MD *h)
 
int px_find_digest (const char *name, PX_MD **res)
 
static void free_openssl_cipher (OSSLCipher *od)
 
static void cipher_free_callback (ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
 
static unsigned gen_ossl_block_size (PX_Cipher *c)
 
static unsigned gen_ossl_key_size (PX_Cipher *c)
 
static unsigned gen_ossl_iv_size (PX_Cipher *c)
 
static void gen_ossl_free (PX_Cipher *c)
 
static int gen_ossl_decrypt (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
static int gen_ossl_encrypt (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
static int bf_check_supported_key_len (void)
 
static int bf_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_des_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_des3_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_cast_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_aes_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_aes_ecb_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
static int ossl_aes_cbc_init (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
int px_find_cipher (const char *name, PX_Cipher **res)
 

Variables

static OSSLDigestopen_digests = NULL
 
static bool digest_resowner_callback_registered = false
 
static int px_openssl_initialized = 0
 
static OSSLCipheropen_ciphers = NULL
 
static bool cipher_resowner_callback_registered = false
 
static PX_Alias ossl_aliases []
 
static const struct ossl_cipher ossl_bf_cbc
 
static const struct ossl_cipher ossl_bf_ecb
 
static const struct ossl_cipher ossl_bf_cfb
 
static const struct ossl_cipher ossl_des_ecb
 
static const struct ossl_cipher ossl_des_cbc
 
static const struct ossl_cipher ossl_des3_ecb
 
static const struct ossl_cipher ossl_des3_cbc
 
static const struct ossl_cipher ossl_cast_ecb
 
static const struct ossl_cipher ossl_cast_cbc
 
static const struct ossl_cipher ossl_aes_ecb
 
static const struct ossl_cipher ossl_aes_cbc
 
static const struct ossl_cipher_lookup ossl_cipher_types []
 

Macro Definition Documentation

◆ MAX_IV

#define MAX_IV   (128/8)

Definition at line 46 of file openssl.c.

◆ MAX_KEY

#define MAX_KEY   (512/8)

Definition at line 45 of file openssl.c.

Typedef Documentation

◆ ossl_EVP_cipher_func

typedef const EVP_CIPHER*(* ossl_EVP_cipher_func) (void)

Definition at line 252 of file openssl.c.

◆ OSSLCipher

typedef struct OSSLCipher OSSLCipher

◆ OSSLDigest

typedef struct OSSLDigest OSSLDigest

Function Documentation

◆ bf_check_supported_key_len()

static int bf_check_supported_key_len ( void  )
static

Definition at line 427 of file openssl.c.

References OSSLCipher::evp_ctx, sort-test::key, and status().

Referenced by bf_init().

428 {
429  static const uint8 key[56] = {
430  0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
431  0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
432  0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
433  0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
434  0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
435  0xff, 0xff, 0xff, 0xff, 0xff, 0xff
436  };
437 
438  static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
439  static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
440  uint8 out[8];
441  EVP_CIPHER_CTX *evp_ctx;
442  int outlen;
443  int status = 0;
444 
445  /* encrypt with 448bits key and verify output */
446  evp_ctx = EVP_CIPHER_CTX_new();
447  if (!evp_ctx)
448  return 0;
449  if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))
450  goto leave;
451  if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))
452  goto leave;
453  if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL))
454  goto leave;
455 
456  if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8))
457  goto leave;
458 
459  if (memcmp(out, res, 8) != 0)
460  goto leave; /* Output does not match -> strong cipher is
461  * not supported */
462  status = 1;
463 
464 leave:
465  EVP_CIPHER_CTX_free(evp_ctx);
466  return status;
467 }
unsigned char uint8
Definition: c.h:439
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227

◆ bf_init()

static int bf_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 470 of file openssl.c.

References bf_check_supported_key_len(), gen_ossl_block_size(), OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, px_cipher::ptr, and PXE_KEY_TOO_BIG.

471 {
472  OSSLCipher *od = c->ptr;
473  unsigned bs = gen_ossl_block_size(c);
474  static int bf_is_strong = -1;
475 
476  /*
477  * Test if key len is supported. BF_set_key silently cut large keys and it
478  * could be a problem when user transfer crypted data from one server to
479  * another.
480  */
481 
482  if (bf_is_strong == -1)
483  bf_is_strong = bf_check_supported_key_len();
484 
485  if (!bf_is_strong && klen > 16)
486  return PXE_KEY_TOO_BIG;
487 
488  /* Key len is supported. We can use it. */
489  od->klen = klen;
490  memcpy(od->key, key, klen);
491 
492  if (iv)
493  memcpy(od->iv, iv, bs);
494  else
495  memset(od->iv, 0, bs);
496  return 0;
497 }
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
uint8 key[MAX_KEY]
Definition: openssl.c:277
unsigned klen
Definition: openssl.c:279
#define PXE_KEY_TOO_BIG
Definition: px.h:53
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
static int bf_check_supported_key_len(void)
Definition: openssl.c:427
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ cipher_free_callback()

static void cipher_free_callback ( ResourceReleasePhase  phase,
bool  isCommit,
bool  isTopLevel,
void *  arg 
)
static

Definition at line 308 of file openssl.c.

References CurrentResourceOwner, elog, free_openssl_cipher(), OSSLDigest::next, OSSLCipher::next, open_ciphers, OSSLCipher::owner, RESOURCE_RELEASE_AFTER_LOCKS, and WARNING.

Referenced by px_find_cipher().

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 }
static int32 next
Definition: blutils.c:219
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:292
static OSSLCipher * open_ciphers
Definition: openssl.c:288
struct OSSLCipher * next
Definition: openssl.c:284
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:232
ResourceOwner owner
Definition: openssl.c:283

◆ digest_block_size()

static unsigned digest_block_size ( PX_MD h)
static

Definition at line 126 of file openssl.c.

References OSSLDigest::ctx, elog, ERROR, px_digest::p, and px_digest::ptr.

Referenced by px_find_digest().

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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
#define ERROR
Definition: elog.h:46
union px_digest::@9 p
#define elog(elevel,...)
Definition: elog.h:232

◆ digest_finish()

static void digest_finish ( PX_MD h,
uint8 dst 
)
static

Definition at line 156 of file openssl.c.

References OSSLDigest::ctx, elog, ERROR, px_digest::p, and px_digest::ptr.

Referenced by px_find_digest().

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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
#define ERROR
Definition: elog.h:46
union px_digest::@9 p
#define elog(elevel,...)
Definition: elog.h:232

◆ digest_free()

static void digest_free ( PX_MD h)
static

Definition at line 165 of file openssl.c.

References free_openssl_digest(), px_digest::p, pfree(), and px_digest::ptr.

Referenced by px_find_digest().

166 {
167  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
168 
169  free_openssl_digest(digest);
170  pfree(h);
171 }
void * ptr
Definition: px.h:110
void pfree(void *pointer)
Definition: mcxt.c:1169
union px_digest::@9 p
static void free_openssl_digest(OSSLDigest *digest)
Definition: openssl.c:71

◆ digest_free_callback()

static void digest_free_callback ( ResourceReleasePhase  phase,
bool  isCommit,
bool  isTopLevel,
void *  arg 
)
static

Definition at line 87 of file openssl.c.

References CurrentResourceOwner, elog, free_openssl_digest(), OSSLDigest::next, open_digests, OSSLDigest::owner, RESOURCE_RELEASE_AFTER_LOCKS, and WARNING.

Referenced by px_find_digest().

91 {
92  OSSLDigest *curr;
94 
95  if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
96  return;
97 
98  next = open_digests;
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 }
ResourceOwner owner
Definition: openssl.c:62
static int32 next
Definition: blutils.c:219
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static OSSLDigest * open_digests
Definition: openssl.c:67
struct OSSLDigest * next
Definition: openssl.c:63
#define WARNING
Definition: elog.h:40
static void free_openssl_digest(OSSLDigest *digest)
Definition: openssl.c:71
#define elog(elevel,...)
Definition: elog.h:232

◆ digest_reset()

static void digest_reset ( PX_MD h)
static

Definition at line 138 of file openssl.c.

References OSSLDigest::algo, OSSLDigest::ctx, elog, ERROR, px_digest::p, and px_digest::ptr.

Referenced by px_find_digest().

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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
const EVP_MD * algo
Definition: openssl.c:59
#define ERROR
Definition: elog.h:46
union px_digest::@9 p
#define elog(elevel,...)
Definition: elog.h:232

◆ digest_result_size()

static unsigned digest_result_size ( PX_MD h)
static

Definition at line 114 of file openssl.c.

References OSSLDigest::ctx, elog, ERROR, px_digest::p, and px_digest::ptr.

Referenced by px_find_digest().

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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
#define ERROR
Definition: elog.h:46
union px_digest::@9 p
#define elog(elevel,...)
Definition: elog.h:232

◆ digest_update()

static void digest_update ( PX_MD h,
const uint8 data,
unsigned  dlen 
)
static

Definition at line 147 of file openssl.c.

References OSSLDigest::ctx, elog, ERROR, px_digest::p, and px_digest::ptr.

Referenced by px_find_digest().

148 {
149  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
150 
151  if (!EVP_DigestUpdate(digest->ctx, data, dlen))
152  elog(ERROR, "EVP_DigestUpdate() failed");
153 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
#define ERROR
Definition: elog.h:46
union px_digest::@9 p
#define elog(elevel,...)
Definition: elog.h:232

◆ free_openssl_cipher()

static void free_openssl_cipher ( OSSLCipher od)
static

Definition at line 292 of file openssl.c.

References OSSLCipher::evp_ctx, OSSLCipher::next, pfree(), and OSSLCipher::prev.

Referenced by cipher_free_callback(), and gen_ossl_free().

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 }
struct OSSLCipher * prev
Definition: openssl.c:285
static OSSLCipher * open_ciphers
Definition: openssl.c:288
struct OSSLCipher * next
Definition: openssl.c:284
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:275
void pfree(void *pointer)
Definition: mcxt.c:1169

◆ free_openssl_digest()

static void free_openssl_digest ( OSSLDigest digest)
static

Definition at line 71 of file openssl.c.

References OSSLDigest::ctx, OSSLDigest::next, pfree(), and OSSLDigest::prev.

Referenced by digest_free(), and digest_free_callback().

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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void pfree(void *pointer)
Definition: mcxt.c:1169
struct OSSLDigest * prev
Definition: openssl.c:64
static OSSLDigest * open_digests
Definition: openssl.c:67
struct OSSLDigest * next
Definition: openssl.c:63

◆ gen_ossl_block_size()

static unsigned gen_ossl_block_size ( PX_Cipher c)
static

Definition at line 337 of file openssl.c.

References ossl_cipher::block_size, OSSLCipher::ciph, and px_cipher::ptr.

Referenced by bf_init(), ossl_aes_init(), ossl_cast_init(), ossl_des3_init(), ossl_des_init(), and px_find_cipher().

338 {
339  OSSLCipher *od = (OSSLCipher *) c->ptr;
340 
341  return od->ciph->block_size;
342 }
void * ptr
Definition: px.h:150
int block_size
Definition: openssl.c:261
const struct ossl_cipher * ciph
Definition: openssl.c:281

◆ gen_ossl_decrypt()

static int gen_ossl_decrypt ( PX_Cipher c,
const uint8 data,
unsigned  dlen,
uint8 res 
)
static

Definition at line 372 of file openssl.c.

References OSSLCipher::evp_ciph, OSSLCipher::evp_ctx, OSSLCipher::init, OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, px_cipher::ptr, PXE_CIPHER_INIT, and PXE_DECRYPT_FAILED.

Referenced by px_find_cipher().

374 {
375  OSSLCipher *od = c->ptr;
376  int outlen;
377 
378  if (!od->init)
379  {
380  if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
381  return PXE_CIPHER_INIT;
382  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
383  return PXE_CIPHER_INIT;
384  if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
385  return PXE_CIPHER_INIT;
386  od->init = true;
387  }
388 
389  if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
390  return PXE_DECRYPT_FAILED;
391 
392  return 0;
393 }
unsigned init
Definition: openssl.c:280
#define PXE_DECRYPT_FAILED
Definition: px.h:63
void * ptr
Definition: px.h:150
uint8 key[MAX_KEY]
Definition: openssl.c:277
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:275
unsigned klen
Definition: openssl.c:279
#define PXE_CIPHER_INIT
Definition: px.h:54
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ gen_ossl_encrypt()

static int gen_ossl_encrypt ( PX_Cipher c,
const uint8 data,
unsigned  dlen,
uint8 res 
)
static

Definition at line 396 of file openssl.c.

References OSSLCipher::evp_ciph, OSSLCipher::evp_ctx, OSSLCipher::init, OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, px_cipher::ptr, PXE_CIPHER_INIT, and PXE_ENCRYPT_FAILED.

Referenced by px_find_cipher().

398 {
399  OSSLCipher *od = c->ptr;
400  int outlen;
401 
402  if (!od->init)
403  {
404  if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
405  return PXE_CIPHER_INIT;
406  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
407  return PXE_CIPHER_INIT;
408  if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
409  return PXE_CIPHER_INIT;
410  od->init = true;
411  }
412 
413  if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
414  return PXE_ENCRYPT_FAILED;
415 
416  return 0;
417 }
unsigned init
Definition: openssl.c:280
void * ptr
Definition: px.h:150
uint8 key[MAX_KEY]
Definition: openssl.c:277
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:275
unsigned klen
Definition: openssl.c:279
#define PXE_ENCRYPT_FAILED
Definition: px.h:64
#define PXE_CIPHER_INIT
Definition: px.h:54
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ gen_ossl_free()

static void gen_ossl_free ( PX_Cipher c)
static

Definition at line 363 of file openssl.c.

References free_openssl_cipher(), pfree(), and px_cipher::ptr.

Referenced by px_find_cipher().

364 {
365  OSSLCipher *od = (OSSLCipher *) c->ptr;
366 
368  pfree(c);
369 }
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:292
void * ptr
Definition: px.h:150
void pfree(void *pointer)
Definition: mcxt.c:1169

◆ gen_ossl_iv_size()

static unsigned gen_ossl_iv_size ( PX_Cipher c)
static

Definition at line 353 of file openssl.c.

References ossl_cipher::block_size, OSSLCipher::ciph, and px_cipher::ptr.

Referenced by px_find_cipher().

354 {
355  unsigned ivlen;
356  OSSLCipher *od = (OSSLCipher *) c->ptr;
357 
358  ivlen = od->ciph->block_size;
359  return ivlen;
360 }
void * ptr
Definition: px.h:150
int block_size
Definition: openssl.c:261
const struct ossl_cipher * ciph
Definition: openssl.c:281

◆ gen_ossl_key_size()

static unsigned gen_ossl_key_size ( PX_Cipher c)
static

Definition at line 345 of file openssl.c.

References OSSLCipher::ciph, ossl_cipher::max_key_size, and px_cipher::ptr.

Referenced by px_find_cipher().

346 {
347  OSSLCipher *od = (OSSLCipher *) c->ptr;
348 
349  return od->ciph->max_key_size;
350 }
int max_key_size
Definition: openssl.c:262
void * ptr
Definition: px.h:150
const struct ossl_cipher * ciph
Definition: openssl.c:281

◆ ossl_aes_cbc_init()

static int ossl_aes_cbc_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 613 of file openssl.c.

References OSSLCipher::evp_ciph, OSSLCipher::klen, ossl_aes_init(), px_cipher::ptr, and PXE_CIPHER_INIT.

614 {
615  OSSLCipher *od = c->ptr;
616  int err;
617 
618  err = ossl_aes_init(c, key, klen, iv);
619  if (err)
620  return err;
621 
622  switch (od->klen)
623  {
624  case 128 / 8:
625  od->evp_ciph = EVP_aes_128_cbc();
626  break;
627  case 192 / 8:
628  od->evp_ciph = EVP_aes_192_cbc();
629  break;
630  case 256 / 8:
631  od->evp_ciph = EVP_aes_256_cbc();
632  break;
633  default:
634  /* shouldn't happen */
635  err = PXE_CIPHER_INIT;
636  break;
637  }
638 
639  return err;
640 }
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:558
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
unsigned klen
Definition: openssl.c:279
#define PXE_CIPHER_INIT
Definition: px.h:54
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276

◆ ossl_aes_ecb_init()

static int ossl_aes_ecb_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 583 of file openssl.c.

References OSSLCipher::evp_ciph, OSSLCipher::klen, ossl_aes_init(), px_cipher::ptr, and PXE_CIPHER_INIT.

584 {
585  OSSLCipher *od = c->ptr;
586  int err;
587 
588  err = ossl_aes_init(c, key, klen, iv);
589  if (err)
590  return err;
591 
592  switch (od->klen)
593  {
594  case 128 / 8:
595  od->evp_ciph = EVP_aes_128_ecb();
596  break;
597  case 192 / 8:
598  od->evp_ciph = EVP_aes_192_ecb();
599  break;
600  case 256 / 8:
601  od->evp_ciph = EVP_aes_256_ecb();
602  break;
603  default:
604  /* shouldn't happen */
605  err = PXE_CIPHER_INIT;
606  break;
607  }
608 
609  return err;
610 }
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:558
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
unsigned klen
Definition: openssl.c:279
#define PXE_CIPHER_INIT
Definition: px.h:54
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276

◆ ossl_aes_init()

static int ossl_aes_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 558 of file openssl.c.

References gen_ossl_block_size(), OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, px_cipher::ptr, and PXE_KEY_TOO_BIG.

Referenced by ossl_aes_cbc_init(), and ossl_aes_ecb_init().

559 {
560  OSSLCipher *od = c->ptr;
561  unsigned bs = gen_ossl_block_size(c);
562 
563  if (klen <= 128 / 8)
564  od->klen = 128 / 8;
565  else if (klen <= 192 / 8)
566  od->klen = 192 / 8;
567  else if (klen <= 256 / 8)
568  od->klen = 256 / 8;
569  else
570  return PXE_KEY_TOO_BIG;
571 
572  memcpy(od->key, key, klen);
573 
574  if (iv)
575  memcpy(od->iv, iv, bs);
576  else
577  memset(od->iv, 0, bs);
578 
579  return 0;
580 }
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
uint8 key[MAX_KEY]
Definition: openssl.c:277
unsigned klen
Definition: openssl.c:279
#define PXE_KEY_TOO_BIG
Definition: px.h:53
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ ossl_cast_init()

static int ossl_cast_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 540 of file openssl.c.

References gen_ossl_block_size(), OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, and px_cipher::ptr.

541 {
542  OSSLCipher *od = c->ptr;
543  unsigned bs = gen_ossl_block_size(c);
544 
545  od->klen = klen;
546  memcpy(od->key, key, klen);
547 
548  if (iv)
549  memcpy(od->iv, iv, bs);
550  else
551  memset(od->iv, 0, bs);
552  return 0;
553 }
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
uint8 key[MAX_KEY]
Definition: openssl.c:277
unsigned klen
Definition: openssl.c:279
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ ossl_des3_init()

static int ossl_des3_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 521 of file openssl.c.

References gen_ossl_block_size(), OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, and px_cipher::ptr.

522 {
523  OSSLCipher *od = c->ptr;
524  unsigned bs = gen_ossl_block_size(c);
525 
526  od->klen = 24;
527  memset(od->key, 0, 24);
528  memcpy(od->key, key, klen > 24 ? 24 : klen);
529 
530  if (iv)
531  memcpy(od->iv, iv, bs);
532  else
533  memset(od->iv, 0, bs);
534  return 0;
535 }
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
uint8 key[MAX_KEY]
Definition: openssl.c:277
unsigned klen
Definition: openssl.c:279
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ ossl_des_init()

static int ossl_des_init ( PX_Cipher c,
const uint8 key,
unsigned  klen,
const uint8 iv 
)
static

Definition at line 502 of file openssl.c.

References gen_ossl_block_size(), OSSLCipher::iv, OSSLCipher::key, OSSLCipher::klen, and px_cipher::ptr.

503 {
504  OSSLCipher *od = c->ptr;
505  unsigned bs = gen_ossl_block_size(c);
506 
507  od->klen = 8;
508  memset(od->key, 0, 8);
509  memcpy(od->key, key, klen > 8 ? 8 : klen);
510 
511  if (iv)
512  memcpy(od->iv, iv, bs);
513  else
514  memset(od->iv, 0, bs);
515  return 0;
516 }
void * ptr
Definition: px.h:150
uint8 iv[INT_MAX_IV]
Definition: internal.c:222
uint8 key[MAX_KEY]
Definition: openssl.c:277
unsigned klen
Definition: openssl.c:279
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
uint8 iv[MAX_IV]
Definition: openssl.c:278

◆ px_find_cipher()

int px_find_cipher ( const char *  name,
PX_Cipher **  res 
)

Definition at line 759 of file openssl.c.

References px_cipher::block_size, OSSLCipher::ciph, ossl_cipher_lookup::ciph, cipher_free_callback(), ossl_cipher::cipher_func, cipher_resowner_callback_registered, OSSLDigest::ctx, CurrentResourceOwner, px_cipher::decrypt, px_cipher::encrypt, OSSLCipher::evp_ciph, OSSLCipher::evp_ctx, px_cipher::free, gen_ossl_block_size(), gen_ossl_decrypt(), gen_ossl_encrypt(), gen_ossl_free(), gen_ossl_iv_size(), gen_ossl_key_size(), i, px_cipher::init, ossl_cipher::init, px_cipher::iv_size, px_cipher::key_size, int_cipher::load, MemoryContextAllocZero(), int_cipher::name, ossl_cipher_lookup::name, OSSLCipher::next, open_ciphers, OSSLCipher::owner, palloc(), pfree(), OSSLCipher::prev, px_cipher::ptr, px_resolve_alias(), PXE_CIPHER_INIT, PXE_NO_CIPHER, RegisterResourceReleaseCallback(), and TopMemoryContext.

760 {
761  const struct ossl_cipher_lookup *i;
762  PX_Cipher *c = NULL;
763  EVP_CIPHER_CTX *ctx;
764  OSSLCipher *od;
765 
767  for (i = ossl_cipher_types; i->name; i++)
768  if (strcmp(i->name, name) == 0)
769  break;
770  if (i->name == NULL)
771  return PXE_NO_CIPHER;
772 
774  {
777  }
778 
779  /*
780  * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
781  * The order is crucial, to make sure we don't leak anything on
782  * out-of-memory or other error.
783  */
784  od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
785  od->ciph = i->ciph;
786 
787  /* Allocate an EVP_CIPHER_CTX object. */
788  ctx = EVP_CIPHER_CTX_new();
789  if (!ctx)
790  {
791  pfree(od);
792  return PXE_CIPHER_INIT;
793  }
794 
795  od->evp_ctx = ctx;
797  od->next = open_ciphers;
798  od->prev = NULL;
799  open_ciphers = od;
800 
801  if (i->ciph->cipher_func)
802  od->evp_ciph = i->ciph->cipher_func();
803 
804  /* The PX_Cipher is allocated in current memory context */
805  c = palloc(sizeof(*c));
809  c->free = gen_ossl_free;
810  c->init = od->ciph->init;
813  c->ptr = od;
814 
815  *res = c;
816  return 0;
817 }
static bool cipher_resowner_callback_registered
Definition: openssl.c:289
struct OSSLCipher * prev
Definition: openssl.c:285
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static void cipher_free_callback(ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
Definition: openssl.c:308
unsigned(* block_size)(PX_Cipher *c)
Definition: px.h:141
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
static OSSLCipher * open_ciphers
Definition: openssl.c:288
void(* free)(PX_Cipher *c)
Definition: px.h:148
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:259
struct OSSLCipher * next
Definition: openssl.c:284
static void gen_ossl_free(PX_Cipher *c)
Definition: openssl.c:363
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:275
void pfree(void *pointer)
Definition: mcxt.c:1169
const char * name
Definition: openssl.c:737
unsigned(* iv_size)(PX_Cipher *c)
Definition: px.h:143
char * c
static unsigned gen_ossl_key_size(PX_Cipher *c)
Definition: openssl.c:345
unsigned(* key_size)(PX_Cipher *c)
Definition: px.h:142
MemoryContext TopMemoryContext
Definition: mcxt.c:48
int(* encrypt)(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: px.h:146
ossl_EVP_cipher_func cipher_func
Definition: openssl.c:260
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
static const struct ossl_cipher_lookup ossl_cipher_types[]
Definition: openssl.c:741
static int gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: openssl.c:396
#define PXE_CIPHER_INIT
Definition: px.h:54
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:337
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: px.h:145
Definition: px.h:139
static PX_Alias ossl_aliases[]
Definition: openssl.c:646
const char * name
Definition: encode.c:515
static unsigned gen_ossl_iv_size(PX_Cipher *c)
Definition: openssl.c:353
const struct ossl_cipher * ciph
Definition: openssl.c:738
void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
Definition: resowner.c:849
void * palloc(Size size)
Definition: mcxt.c:1062
const struct ossl_cipher * ciph
Definition: openssl.c:281
int i
#define PXE_NO_CIPHER
Definition: px.h:49
ResourceOwner owner
Definition: openssl.c:283
const EVP_CIPHER * evp_ciph
Definition: openssl.c:276
static int gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: openssl.c:372

◆ px_find_digest()

int px_find_digest ( const char *  name,
PX_MD **  res 
)

Definition at line 178 of file openssl.c.

References OSSLDigest::algo, px_digest::block_size, OSSLDigest::ctx, CurrentResourceOwner, digest_block_size(), digest_finish(), digest_free(), digest_free_callback(), digest_reset(), digest_resowner_callback_registered, digest_result_size(), digest_update(), px_digest::finish, px_digest::free, int_digest::init, MemoryContextAlloc(), int_digest::name, OSSLDigest::next, open_digests, OSSLDigest::owner, px_digest::p, palloc(), pfree(), pg_strcasecmp(), OSSLDigest::prev, px_digest::ptr, px_openssl_initialized, PXE_NO_HASH, RegisterResourceReleaseCallback(), px_digest::reset, px_digest::result_size, TopMemoryContext, and px_digest::update.

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 -1;
213  }
214  if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
215  {
216  EVP_MD_CTX_destroy(ctx);
217  pfree(digest);
218  return -1;
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 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:110
ResourceOwner owner
Definition: openssl.c:62
static bool digest_resowner_callback_registered
Definition: openssl.c:68
void(* free)(PX_MD *h)
Definition: px.h:105
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
const EVP_MD * algo
Definition: openssl.c:59
static int px_openssl_initialized
Definition: openssl.c:173
void pfree(void *pointer)
Definition: mcxt.c:1169
unsigned(* block_size)(PX_MD *h)
Definition: px.h:101
struct OSSLDigest * prev
Definition: openssl.c:64
union px_digest::@9 p
Definition: px.h:98
static OSSLDigest * open_digests
Definition: openssl.c:67
static void digest_free_callback(ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
Definition: openssl.c:87
#define PXE_NO_HASH
Definition: px.h:48
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: px.h:103
void(* finish)(PX_MD *h, uint8 *dst)
Definition: px.h:104
static unsigned digest_block_size(PX_MD *h)
Definition: openssl.c:126
static void digest_finish(PX_MD *h, uint8 *dst)
Definition: openssl.c:156
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static void digest_free(PX_MD *h)
Definition: openssl.c:165
struct OSSLDigest * next
Definition: openssl.c:63
unsigned(* result_size)(PX_MD *h)
Definition: px.h:100
void(* reset)(PX_MD *h)
Definition: px.h:102
const char * name
Definition: encode.c:515
static unsigned digest_result_size(PX_MD *h)
Definition: openssl.c:114
void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
Definition: resowner.c:849
void * palloc(Size size)
Definition: mcxt.c:1062
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: openssl.c:147
static void digest_reset(PX_MD *h)
Definition: openssl.c:138

Variable Documentation

◆ cipher_resowner_callback_registered

bool cipher_resowner_callback_registered = false
static

Definition at line 289 of file openssl.c.

Referenced by px_find_cipher().

◆ digest_resowner_callback_registered

bool digest_resowner_callback_registered = false
static

Definition at line 68 of file openssl.c.

Referenced by px_find_digest().

◆ open_ciphers

OSSLCipher* open_ciphers = NULL
static

Definition at line 288 of file openssl.c.

Referenced by cipher_free_callback(), and px_find_cipher().

◆ open_digests

OSSLDigest* open_digests = NULL
static

Definition at line 67 of file openssl.c.

Referenced by digest_free_callback(), and px_find_digest().

◆ ossl_aes_cbc

const struct ossl_cipher ossl_aes_cbc
static
Initial value:
= {
NULL,
128 / 8, 256 / 8
}
static int ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:613

Definition at line 725 of file openssl.c.

◆ ossl_aes_ecb

const struct ossl_cipher ossl_aes_ecb
static
Initial value:
= {
NULL,
128 / 8, 256 / 8
}
static int ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:583

Definition at line 718 of file openssl.c.

◆ ossl_aliases

PX_Alias ossl_aliases[]
static
Initial value:
= {
{"bf", "bf-cbc"},
{"blowfish", "bf-cbc"},
{"blowfish-cbc", "bf-cbc"},
{"blowfish-ecb", "bf-ecb"},
{"blowfish-cfb", "bf-cfb"},
{"des", "des-cbc"},
{"3des", "des3-cbc"},
{"3des-ecb", "des3-ecb"},
{"3des-cbc", "des3-cbc"},
{"cast5", "cast5-cbc"},
{"aes", "aes-cbc"},
{"rijndael", "aes-cbc"},
{"rijndael-cbc", "aes-cbc"},
{"rijndael-ecb", "aes-ecb"},
{NULL}
}

Definition at line 646 of file openssl.c.

◆ ossl_bf_cbc

const struct ossl_cipher ossl_bf_cbc
static
Initial value:
= {
EVP_bf_cbc,
64 / 8, 448 / 8
}
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:470

Definition at line 664 of file openssl.c.

◆ ossl_bf_cfb

const struct ossl_cipher ossl_bf_cfb
static
Initial value:
= {
EVP_bf_cfb,
64 / 8, 448 / 8
}
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:470

Definition at line 676 of file openssl.c.

◆ ossl_bf_ecb

const struct ossl_cipher ossl_bf_ecb
static
Initial value:
= {
EVP_bf_ecb,
64 / 8, 448 / 8
}
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:470

Definition at line 670 of file openssl.c.

◆ ossl_cast_cbc

const struct ossl_cipher ossl_cast_cbc
static
Initial value:
= {
EVP_cast5_cbc,
64 / 8, 128 / 8
}
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:540

Definition at line 712 of file openssl.c.

◆ ossl_cast_ecb

const struct ossl_cipher ossl_cast_ecb
static
Initial value:
= {
EVP_cast5_ecb,
64 / 8, 128 / 8
}
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:540

Definition at line 706 of file openssl.c.

◆ ossl_cipher_types

const struct ossl_cipher_lookup ossl_cipher_types[]
static
Initial value:
= {
{"bf-cbc", &ossl_bf_cbc},
{"bf-ecb", &ossl_bf_ecb},
{"bf-cfb", &ossl_bf_cfb},
{"des-ecb", &ossl_des_ecb},
{"des-cbc", &ossl_des_cbc},
{"des3-ecb", &ossl_des3_ecb},
{"des3-cbc", &ossl_des3_cbc},
{"cast5-ecb", &ossl_cast_ecb},
{"cast5-cbc", &ossl_cast_cbc},
{"aes-ecb", &ossl_aes_ecb},
{"aes-cbc", &ossl_aes_cbc},
{NULL}
}
static const struct ossl_cipher ossl_cast_cbc
Definition: openssl.c:712
static const struct ossl_cipher ossl_des3_ecb
Definition: openssl.c:694
static const struct ossl_cipher ossl_aes_cbc
Definition: openssl.c:725
static const struct ossl_cipher ossl_des_ecb
Definition: openssl.c:682
static const struct ossl_cipher ossl_bf_cfb
Definition: openssl.c:676
static const struct ossl_cipher ossl_aes_ecb
Definition: openssl.c:718
static const struct ossl_cipher ossl_des3_cbc
Definition: openssl.c:700
static const struct ossl_cipher ossl_cast_ecb
Definition: openssl.c:706
static const struct ossl_cipher ossl_bf_ecb
Definition: openssl.c:670
static const struct ossl_cipher ossl_des_cbc
Definition: openssl.c:688
static const struct ossl_cipher ossl_bf_cbc
Definition: openssl.c:664

Definition at line 741 of file openssl.c.

◆ ossl_des3_cbc

const struct ossl_cipher ossl_des3_cbc
static
Initial value:
= {
EVP_des_ede3_cbc,
64 / 8, 192 / 8
}
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:521

Definition at line 700 of file openssl.c.

◆ ossl_des3_ecb

const struct ossl_cipher ossl_des3_ecb
static
Initial value:
= {
EVP_des_ede3_ecb,
64 / 8, 192 / 8
}
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:521

Definition at line 694 of file openssl.c.

◆ ossl_des_cbc

const struct ossl_cipher ossl_des_cbc
static
Initial value:
= {
EVP_des_cbc,
64 / 8, 64 / 8
}
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:502

Definition at line 688 of file openssl.c.

◆ ossl_des_ecb

const struct ossl_cipher ossl_des_ecb
static
Initial value:
= {
EVP_des_ecb,
64 / 8, 64 / 8
}
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:502

Definition at line 682 of file openssl.c.

◆ px_openssl_initialized

int px_openssl_initialized = 0
static

Definition at line 173 of file openssl.c.

Referenced by px_find_digest().