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 240 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 415 of file openssl.c.

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

Referenced by bf_init().

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

◆ bf_init()

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

Definition at line 458 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.

459 {
460  OSSLCipher *od = c->ptr;
461  unsigned bs = gen_ossl_block_size(c);
462  static int bf_is_strong = -1;
463 
464  /*
465  * Test if key len is supported. BF_set_key silently cut large keys and it
466  * could be a problem when user transfer crypted data from one server to
467  * another.
468  */
469 
470  if (bf_is_strong == -1)
471  bf_is_strong = bf_check_supported_key_len();
472 
473  if (!bf_is_strong && klen > 16)
474  return PXE_KEY_TOO_BIG;
475 
476  /* Key len is supported. We can use it. */
477  od->klen = klen;
478  memcpy(od->key, key, klen);
479 
480  if (iv)
481  memcpy(od->iv, iv, bs);
482  else
483  memset(od->iv, 0, bs);
484  return 0;
485 }
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
uint8 key[MAX_KEY]
Definition: openssl.c:265
unsigned klen
Definition: openssl.c:267
#define PXE_KEY_TOO_BIG
Definition: px.h:66
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
static int bf_check_supported_key_len(void)
Definition: openssl.c:415
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ cipher_free_callback()

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

Definition at line 296 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().

300 {
301  OSSLCipher *curr;
302  OSSLCipher *next;
303 
304  if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
305  return;
306 
307  next = open_ciphers;
308  while (next)
309  {
310  curr = next;
311  next = curr->next;
312 
313  if (curr->owner == CurrentResourceOwner)
314  {
315  if (isCommit)
316  elog(WARNING, "pgcrypto cipher reference leak: cipher %p still referenced", curr);
317  free_openssl_cipher(curr);
318  }
319  }
320 }
static int32 next
Definition: blutils.c:213
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:280
static OSSLCipher * open_ciphers
Definition: openssl.c:276
struct OSSLCipher * next
Definition: openssl.c:272
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:228
ResourceOwner owner
Definition: openssl.c:271

◆ digest_block_size()

static unsigned digest_block_size ( PX_MD h)
static

Definition at line 122 of file openssl.c.

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

Referenced by px_find_digest().

123 {
124  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
125 
126  return EVP_MD_CTX_block_size(digest->ctx);
127 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
union px_digest::@13 p

◆ digest_finish()

static void digest_finish ( PX_MD h,
uint8 dst 
)
static

Definition at line 146 of file openssl.c.

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

Referenced by px_find_digest().

147 {
148  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
149 
150  EVP_DigestFinal_ex(digest->ctx, dst, NULL);
151 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
union px_digest::@13 p

◆ digest_free()

static void digest_free ( PX_MD h)
static

Definition at line 154 of file openssl.c.

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

Referenced by px_find_digest().

155 {
156  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
157 
158  free_openssl_digest(digest);
159  px_free(h);
160 }
void * ptr
Definition: px.h:122
#define px_free(p)
Definition: px.h:46
union px_digest::@13 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:213
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
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:228

◆ digest_reset()

static void digest_reset ( PX_MD h)
static

Definition at line 130 of file openssl.c.

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

Referenced by px_find_digest().

131 {
132  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
133 
134  EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
135 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
const EVP_MD * algo
Definition: openssl.c:59
union px_digest::@13 p

◆ digest_result_size()

static unsigned digest_result_size ( PX_MD h)
static

Definition at line 114 of file openssl.c.

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

Referenced by px_find_digest().

115 {
116  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
117 
118  return EVP_MD_CTX_size(digest->ctx);
119 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
union px_digest::@13 p

◆ digest_update()

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

Definition at line 138 of file openssl.c.

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

Referenced by px_find_digest().

139 {
140  OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
141 
142  EVP_DigestUpdate(digest->ctx, data, dlen);
143 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
union px_digest::@13 p

◆ free_openssl_cipher()

static void free_openssl_cipher ( OSSLCipher od)
static

Definition at line 280 of file openssl.c.

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

Referenced by cipher_free_callback(), and gen_ossl_free().

281 {
282  EVP_CIPHER_CTX_free(od->evp_ctx);
283  if (od->prev)
284  od->prev->next = od->next;
285  else
286  open_ciphers = od->next;
287  if (od->next)
288  od->next->prev = od->prev;
289  pfree(od);
290 }
struct OSSLCipher * prev
Definition: openssl.c:273
static OSSLCipher * open_ciphers
Definition: openssl.c:276
struct OSSLCipher * next
Definition: openssl.c:272
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:263
void pfree(void *pointer)
Definition: mcxt.c:1056

◆ 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:1056
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 325 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().

326 {
327  OSSLCipher *od = (OSSLCipher *) c->ptr;
328 
329  return od->ciph->block_size;
330 }
void * ptr
Definition: px.h:162
int block_size
Definition: openssl.c:249
const struct ossl_cipher * ciph
Definition: openssl.c:269

◆ gen_ossl_decrypt()

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

Definition at line 360 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().

362 {
363  OSSLCipher *od = c->ptr;
364  int outlen;
365 
366  if (!od->init)
367  {
368  if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
369  return PXE_CIPHER_INIT;
370  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
371  return PXE_CIPHER_INIT;
372  if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
373  return PXE_CIPHER_INIT;
374  od->init = true;
375  }
376 
377  if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
378  return PXE_DECRYPT_FAILED;
379 
380  return 0;
381 }
unsigned init
Definition: openssl.c:268
#define PXE_DECRYPT_FAILED
Definition: px.h:76
void * ptr
Definition: px.h:162
uint8 key[MAX_KEY]
Definition: openssl.c:265
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:263
unsigned klen
Definition: openssl.c:267
#define PXE_CIPHER_INIT
Definition: px.h:67
const EVP_CIPHER * evp_ciph
Definition: openssl.c:264
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ gen_ossl_encrypt()

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

Definition at line 384 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_ERR_GENERIC.

Referenced by px_find_cipher().

386 {
387  OSSLCipher *od = c->ptr;
388  int outlen;
389 
390  if (!od->init)
391  {
392  if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
393  return PXE_CIPHER_INIT;
394  if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
395  return PXE_CIPHER_INIT;
396  if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
397  return PXE_CIPHER_INIT;
398  od->init = true;
399  }
400 
401  if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
402  return PXE_ERR_GENERIC;
403 
404  return 0;
405 }
unsigned init
Definition: openssl.c:268
void * ptr
Definition: px.h:162
uint8 key[MAX_KEY]
Definition: openssl.c:265
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:263
unsigned klen
Definition: openssl.c:267
#define PXE_CIPHER_INIT
Definition: px.h:67
const EVP_CIPHER * evp_ciph
Definition: openssl.c:264
uint8 iv[MAX_IV]
Definition: openssl.c:266
#define PXE_ERR_GENERIC
Definition: px.h:60

◆ gen_ossl_free()

static void gen_ossl_free ( PX_Cipher c)
static

Definition at line 351 of file openssl.c.

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

Referenced by px_find_cipher().

352 {
353  OSSLCipher *od = (OSSLCipher *) c->ptr;
354 
356  px_free(c);
357 }
#define px_free(p)
Definition: px.h:46
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:280
void * ptr
Definition: px.h:162

◆ gen_ossl_iv_size()

static unsigned gen_ossl_iv_size ( PX_Cipher c)
static

Definition at line 341 of file openssl.c.

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

Referenced by px_find_cipher().

342 {
343  unsigned ivlen;
344  OSSLCipher *od = (OSSLCipher *) c->ptr;
345 
346  ivlen = od->ciph->block_size;
347  return ivlen;
348 }
void * ptr
Definition: px.h:162
int block_size
Definition: openssl.c:249
const struct ossl_cipher * ciph
Definition: openssl.c:269

◆ gen_ossl_key_size()

static unsigned gen_ossl_key_size ( PX_Cipher c)
static

Definition at line 333 of file openssl.c.

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

Referenced by px_find_cipher().

334 {
335  OSSLCipher *od = (OSSLCipher *) c->ptr;
336 
337  return od->ciph->max_key_size;
338 }
int max_key_size
Definition: openssl.c:250
void * ptr
Definition: px.h:162
const struct ossl_cipher * ciph
Definition: openssl.c:269

◆ 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 601 of file openssl.c.

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

602 {
603  OSSLCipher *od = c->ptr;
604  int err;
605 
606  err = ossl_aes_init(c, key, klen, iv);
607  if (err)
608  return err;
609 
610  switch (od->klen)
611  {
612  case 128 / 8:
613  od->evp_ciph = EVP_aes_128_cbc();
614  break;
615  case 192 / 8:
616  od->evp_ciph = EVP_aes_192_cbc();
617  break;
618  case 256 / 8:
619  od->evp_ciph = EVP_aes_256_cbc();
620  break;
621  default:
622  /* shouldn't happen */
623  err = PXE_CIPHER_INIT;
624  break;
625  }
626 
627  return err;
628 }
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:546
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
unsigned klen
Definition: openssl.c:267
#define PXE_CIPHER_INIT
Definition: px.h:67
const EVP_CIPHER * evp_ciph
Definition: openssl.c:264

◆ 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 571 of file openssl.c.

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

572 {
573  OSSLCipher *od = c->ptr;
574  int err;
575 
576  err = ossl_aes_init(c, key, klen, iv);
577  if (err)
578  return err;
579 
580  switch (od->klen)
581  {
582  case 128 / 8:
583  od->evp_ciph = EVP_aes_128_ecb();
584  break;
585  case 192 / 8:
586  od->evp_ciph = EVP_aes_192_ecb();
587  break;
588  case 256 / 8:
589  od->evp_ciph = EVP_aes_256_ecb();
590  break;
591  default:
592  /* shouldn't happen */
593  err = PXE_CIPHER_INIT;
594  break;
595  }
596 
597  return err;
598 }
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:546
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
unsigned klen
Definition: openssl.c:267
#define PXE_CIPHER_INIT
Definition: px.h:67
const EVP_CIPHER * evp_ciph
Definition: openssl.c:264

◆ ossl_aes_init()

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

Definition at line 546 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().

547 {
548  OSSLCipher *od = c->ptr;
549  unsigned bs = gen_ossl_block_size(c);
550 
551  if (klen <= 128 / 8)
552  od->klen = 128 / 8;
553  else if (klen <= 192 / 8)
554  od->klen = 192 / 8;
555  else if (klen <= 256 / 8)
556  od->klen = 256 / 8;
557  else
558  return PXE_KEY_TOO_BIG;
559 
560  memcpy(od->key, key, klen);
561 
562  if (iv)
563  memcpy(od->iv, iv, bs);
564  else
565  memset(od->iv, 0, bs);
566 
567  return 0;
568 }
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
uint8 key[MAX_KEY]
Definition: openssl.c:265
unsigned klen
Definition: openssl.c:267
#define PXE_KEY_TOO_BIG
Definition: px.h:66
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ ossl_cast_init()

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

Definition at line 528 of file openssl.c.

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

529 {
530  OSSLCipher *od = c->ptr;
531  unsigned bs = gen_ossl_block_size(c);
532 
533  od->klen = klen;
534  memcpy(od->key, key, klen);
535 
536  if (iv)
537  memcpy(od->iv, iv, bs);
538  else
539  memset(od->iv, 0, bs);
540  return 0;
541 }
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
uint8 key[MAX_KEY]
Definition: openssl.c:265
unsigned klen
Definition: openssl.c:267
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ ossl_des3_init()

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

Definition at line 509 of file openssl.c.

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

510 {
511  OSSLCipher *od = c->ptr;
512  unsigned bs = gen_ossl_block_size(c);
513 
514  od->klen = 24;
515  memset(od->key, 0, 24);
516  memcpy(od->key, key, klen > 24 ? 24 : klen);
517 
518  if (iv)
519  memcpy(od->iv, iv, bs);
520  else
521  memset(od->iv, 0, bs);
522  return 0;
523 }
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
uint8 key[MAX_KEY]
Definition: openssl.c:265
unsigned klen
Definition: openssl.c:267
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ ossl_des_init()

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

Definition at line 490 of file openssl.c.

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

491 {
492  OSSLCipher *od = c->ptr;
493  unsigned bs = gen_ossl_block_size(c);
494 
495  od->klen = 8;
496  memset(od->key, 0, 8);
497  memcpy(od->key, key, klen > 8 ? 8 : klen);
498 
499  if (iv)
500  memcpy(od->iv, iv, bs);
501  else
502  memset(od->iv, 0, bs);
503  return 0;
504 }
void * ptr
Definition: px.h:162
uint8 iv[INT_MAX_IV]
Definition: internal.c:230
uint8 key[MAX_KEY]
Definition: openssl.c:265
unsigned klen
Definition: openssl.c:267
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
uint8 iv[MAX_IV]
Definition: openssl.c:266

◆ px_find_cipher()

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

Definition at line 747 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, pfree(), OSSLCipher::prev, px_cipher::ptr, px_alloc, px_resolve_alias(), PXE_CIPHER_INIT, PXE_NO_CIPHER, RegisterResourceReleaseCallback(), and TopMemoryContext.

748 {
749  const struct ossl_cipher_lookup *i;
750  PX_Cipher *c = NULL;
751  EVP_CIPHER_CTX *ctx;
752  OSSLCipher *od;
753 
755  for (i = ossl_cipher_types; i->name; i++)
756  if (strcmp(i->name, name) == 0)
757  break;
758  if (i->name == NULL)
759  return PXE_NO_CIPHER;
760 
762  {
765  }
766 
767  /*
768  * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
769  * The order is crucial, to make sure we don't leak anything on
770  * out-of-memory or other error.
771  */
772  od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
773  od->ciph = i->ciph;
774 
775  /* Allocate an EVP_CIPHER_CTX object. */
776  ctx = EVP_CIPHER_CTX_new();
777  if (!ctx)
778  {
779  pfree(od);
780  return PXE_CIPHER_INIT;
781  }
782 
783  od->evp_ctx = ctx;
785  od->next = open_ciphers;
786  od->prev = NULL;
787  open_ciphers = od;
788 
789  if (i->ciph->cipher_func)
790  od->evp_ciph = i->ciph->cipher_func();
791 
792  /* The PX_Cipher is allocated in current memory context */
793  c = px_alloc(sizeof(*c));
797  c->free = gen_ossl_free;
798  c->init = od->ciph->init;
801  c->ptr = od;
802 
803  *res = c;
804  return 0;
805 }
static bool cipher_resowner_callback_registered
Definition: openssl.c:277
struct OSSLCipher * prev
Definition: openssl.c:273
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static void cipher_free_callback(ResourceReleasePhase phase, bool isCommit, bool isTopLevel, void *arg)
Definition: openssl.c:296
unsigned(* block_size)(PX_Cipher *c)
Definition: px.h:153
int(* decrypt)(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: px.h:159
const char * px_resolve_alias(const PX_Alias *list, const char *name)
Definition: px.c:132
void * ptr
Definition: px.h:162
static OSSLCipher * open_ciphers
Definition: openssl.c:276
void(* free)(PX_Cipher *c)
Definition: px.h:160
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:247
struct OSSLCipher * next
Definition: openssl.c:272
static void gen_ossl_free(PX_Cipher *c)
Definition: openssl.c:351
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:263
void pfree(void *pointer)
Definition: mcxt.c:1056
const char * name
Definition: openssl.c:725
unsigned(* iv_size)(PX_Cipher *c)
Definition: px.h:155
char * c
static unsigned gen_ossl_key_size(PX_Cipher *c)
Definition: openssl.c:333
unsigned(* key_size)(PX_Cipher *c)
Definition: px.h:154
MemoryContext TopMemoryContext
Definition: mcxt.c:44
int(* encrypt)(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: px.h:158
ossl_EVP_cipher_func cipher_func
Definition: openssl.c:248
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:839
static const struct ossl_cipher_lookup ossl_cipher_types[]
Definition: openssl.c:729
static int gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: openssl.c:384
#define PXE_CIPHER_INIT
Definition: px.h:67
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:325
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: px.h:157
Definition: px.h:151
static PX_Alias ossl_aliases[]
Definition: openssl.c:634
const char * name
Definition: encode.c:521
static unsigned gen_ossl_iv_size(PX_Cipher *c)
Definition: openssl.c:341
#define px_alloc(s)
Definition: px.h:44
const struct ossl_cipher * ciph
Definition: openssl.c:726
void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
Definition: resowner.c:796
const struct ossl_cipher * ciph
Definition: openssl.c:269
int i
#define PXE_NO_CIPHER
Definition: px.h:62
ResourceOwner owner
Definition: openssl.c:271
const EVP_CIPHER * evp_ciph
Definition: openssl.c:264
static int gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
Definition: openssl.c:360

◆ px_find_digest()

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

Definition at line 167 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, pfree(), pg_strcasecmp(), OSSLDigest::prev, px_digest::ptr, px_alloc, px_openssl_initialized, PXE_NO_HASH, RegisterResourceReleaseCallback(), px_digest::reset, px_digest::result_size, TopMemoryContext, and px_digest::update.

168 {
169  const EVP_MD *md;
170  EVP_MD_CTX *ctx;
171  PX_MD *h;
172  OSSLDigest *digest;
173 
175  {
177  OpenSSL_add_all_algorithms();
178  }
179 
181  {
184  }
185 
186  md = EVP_get_digestbyname(name);
187  if (md == NULL)
188  return PXE_NO_HASH;
189 
190  /*
191  * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
192  * The order is crucial, to make sure we don't leak anything on
193  * out-of-memory or other error.
194  */
195  digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
196 
197  ctx = EVP_MD_CTX_create();
198  if (!ctx)
199  {
200  pfree(digest);
201  return -1;
202  }
203  if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
204  {
205  pfree(digest);
206  return -1;
207  }
208 
209  digest->algo = md;
210  digest->ctx = ctx;
211  digest->owner = CurrentResourceOwner;
212  digest->next = open_digests;
213  digest->prev = NULL;
214  open_digests = digest;
215 
216  /* The PX_MD object is allocated in the current memory context. */
217  h = px_alloc(sizeof(*h));
220  h->reset = digest_reset;
221  h->update = digest_update;
222  h->finish = digest_finish;
223  h->free = digest_free;
224  h->p.ptr = (void *) digest;
225 
226  *res = h;
227  return 0;
228 }
EVP_MD_CTX * ctx
Definition: openssl.c:60
void * ptr
Definition: px.h:122
ResourceOwner owner
Definition: openssl.c:62
static bool digest_resowner_callback_registered
Definition: openssl.c:68
void(* free)(PX_MD *h)
Definition: px.h:117
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
const EVP_MD * algo
Definition: openssl.c:59
static int px_openssl_initialized
Definition: openssl.c:162
void pfree(void *pointer)
Definition: mcxt.c:1056
unsigned(* block_size)(PX_MD *h)
Definition: px.h:113
struct OSSLDigest * prev
Definition: openssl.c:64
Definition: px.h:110
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:61
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: px.h:115
void(* finish)(PX_MD *h, uint8 *dst)
Definition: px.h:116
static unsigned digest_block_size(PX_MD *h)
Definition: openssl.c:122
static void digest_finish(PX_MD *h, uint8 *dst)
Definition: openssl.c:146
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static void digest_free(PX_MD *h)
Definition: openssl.c:154
struct OSSLDigest * next
Definition: openssl.c:63
unsigned(* result_size)(PX_MD *h)
Definition: px.h:112
union px_digest::@13 p
void(* reset)(PX_MD *h)
Definition: px.h:114
const char * name
Definition: encode.c:521
#define px_alloc(s)
Definition: px.h:44
static unsigned digest_result_size(PX_MD *h)
Definition: openssl.c:114
void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
Definition: resowner.c:796
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: openssl.c:138
static void digest_reset(PX_MD *h)
Definition: openssl.c:130

Variable Documentation

◆ cipher_resowner_callback_registered

bool cipher_resowner_callback_registered = false
static

Definition at line 277 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 276 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:601

Definition at line 713 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:571

Definition at line 706 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 634 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:458

Definition at line 652 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:458

Definition at line 664 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:458

Definition at line 658 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:528

Definition at line 700 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:528

Definition at line 694 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:700
static const struct ossl_cipher ossl_des3_ecb
Definition: openssl.c:682
static const struct ossl_cipher ossl_aes_cbc
Definition: openssl.c:713
static const struct ossl_cipher ossl_des_ecb
Definition: openssl.c:670
static const struct ossl_cipher ossl_bf_cfb
Definition: openssl.c:664
static const struct ossl_cipher ossl_aes_ecb
Definition: openssl.c:706
static const struct ossl_cipher ossl_des3_cbc
Definition: openssl.c:688
static const struct ossl_cipher ossl_cast_ecb
Definition: openssl.c:694
static const struct ossl_cipher ossl_bf_ecb
Definition: openssl.c:658
static const struct ossl_cipher ossl_des_cbc
Definition: openssl.c:676
static const struct ossl_cipher ossl_bf_cbc
Definition: openssl.c:652

Definition at line 729 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:509

Definition at line 688 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:509

Definition at line 682 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:490

Definition at line 676 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:490

Definition at line 670 of file openssl.c.

◆ px_openssl_initialized

int px_openssl_initialized = 0
static

Definition at line 162 of file openssl.c.

Referenced by px_find_digest().