34#include <openssl/crypto.h>
35#include <openssl/evp.h>
36#include <openssl/err.h>
37#include <openssl/rand.h>
46#define MAX_KEY (512/8)
70 .
name =
"pgcrypto OpenSSL digest handle",
92 EVP_MD_CTX_destroy(digest->
ctx);
93 if (digest->
owner != NULL)
102 int result = EVP_MD_CTX_size(digest->
ctx);
114 int result = EVP_MD_CTX_block_size(digest->
ctx);
117 elog(
ERROR,
"EVP_MD_CTX_block_size() failed");
127 if (!EVP_DigestInit_ex(digest->
ctx, digest->
algo, NULL))
128 elog(
ERROR,
"EVP_DigestInit_ex() failed");
136 if (!EVP_DigestUpdate(digest->
ctx,
data, dlen))
137 elog(
ERROR,
"EVP_DigestUpdate() failed");
145 if (!EVP_DigestFinal_ex(digest->
ctx, dst, NULL))
146 elog(
ERROR,
"EVP_DigestFinal_ex() failed");
168 md = EVP_get_digestbyname(
name);
181 ctx = EVP_MD_CTX_create();
187 if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
189 EVP_MD_CTX_destroy(ctx);
220 digest->
owner = NULL;
234typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);
272 .
name =
"pgcrypto OpenSSL cipher handle",
294 EVP_CIPHER_CTX_free(od->
evp_ctx);
295 if (od->
owner != NULL)
349 if (!EVP_CIPHER_CTX_set_padding(od->
evp_ctx, padding))
351 if (!EVP_CIPHER_CTX_set_key_length(od->
evp_ctx, od->
klen))
353 if (!EVP_DecryptInit_ex(od->
evp_ctx, NULL, NULL, od->
key, od->
iv))
360 if (!EVP_DecryptFinal_ex(od->
evp_ctx,
res + outlen, &outlen2))
362 *rlen = outlen + outlen2;
379 if (!EVP_CIPHER_CTX_set_padding(od->
evp_ctx, padding))
381 if (!EVP_CIPHER_CTX_set_key_length(od->
evp_ctx, od->
klen))
383 if (!EVP_EncryptInit_ex(od->
evp_ctx, NULL, NULL, od->
key, od->
iv))
390 if (!EVP_EncryptFinal_ex(od->
evp_ctx,
res + outlen, &outlen2))
392 *rlen = outlen + outlen2;
408 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
409 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
410 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
411 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
412 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
413 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
416 static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
417 static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
419 EVP_CIPHER_CTX *evp_ctx;
424 evp_ctx = EVP_CIPHER_CTX_new();
427 if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))
429 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))
431 if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL,
key, NULL))
434 if (!EVP_EncryptUpdate(evp_ctx, out, &outlen,
data, 8))
437 if (memcmp(out,
res, 8) != 0)
443 EVP_CIPHER_CTX_free(evp_ctx);
452 static int bf_is_strong = -1;
460 if (bf_is_strong == -1)
463 if (!bf_is_strong && klen > 16)
468 memcpy(od->
key,
key, klen);
471 memcpy(od->
iv, iv, bs);
473 memset(od->
iv, 0, bs);
486 memset(od->
key, 0, 8);
487 memcpy(od->
key,
key, klen > 8 ? 8 : klen);
490 memcpy(od->
iv, iv, bs);
492 memset(od->
iv, 0, bs);
505 memset(od->
key, 0, 24);
506 memcpy(od->
key,
key, klen > 24 ? 24 : klen);
509 memcpy(od->
iv, iv, bs);
511 memset(od->
iv, 0, bs);
524 memcpy(od->
key,
key, klen);
527 memcpy(od->
iv, iv, bs);
529 memset(od->
iv, 0, bs);
543 else if (klen <= 192 / 8)
545 else if (klen <= 256 / 8)
550 memcpy(od->
key,
key, klen);
553 memcpy(od->
iv, iv, bs);
555 memset(od->
iv, 0, bs);
626 {
"blowfish",
"bf-cbc"},
627 {
"blowfish-cbc",
"bf-cbc"},
628 {
"blowfish-ecb",
"bf-ecb"},
629 {
"blowfish-cfb",
"bf-cfb"},
631 {
"3des",
"des3-cbc"},
632 {
"3des-ecb",
"des3-ecb"},
633 {
"3des-cbc",
"des3-cbc"},
634 {
"cast5",
"cast5-cbc"},
636 {
"rijndael",
"aes-cbc"},
637 {
"rijndael-cbc",
"aes-cbc"},
638 {
"rijndael-ecb",
"aes-ecb"},
746 if (strcmp(
i->name,
name) == 0)
762 ctx = EVP_CIPHER_CTX_new();
773 if (
i->ciph->cipher_func)
807 int fips_enabled = 0;
817#if OPENSSL_VERSION_NUMBER >= 0x30000000L
818 EVP_default_properties_is_fips_enabled(NULL);
823 return (fips_enabled == 1);
842 errmsg(
"use of built-in crypto functions is disabled"));
848 errmsg(
"use of non-FIPS validated crypto not allowed when OpenSSL is in FIPS mode"));
#define Assert(condition)
static void PGresult * res
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
if(TABLE==NULL||TABLE_index==NULL)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void pfree(void *pointer)
MemoryContext TopMemoryContext
static unsigned gen_ossl_block_size(PX_Cipher *c)
int px_find_digest(const char *name, PX_MD **res)
void CheckBuiltinCryptoMode(void)
static const struct ossl_cipher ossl_des_ecb
static const struct ossl_cipher ossl_des3_cbc
static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static int bf_check_supported_key_len(void)
static void ResourceOwnerForgetOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
static unsigned digest_result_size(PX_MD *h)
static const struct ossl_cipher ossl_aes_ecb
static void ResourceOwnerRememberOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
static void digest_finish(PX_MD *h, uint8 *dst)
struct OSSLCipher OSSLCipher
static const ResourceOwnerDesc ossldigest_resowner_desc
static void free_openssl_cipher(OSSLCipher *od)
const EVP_CIPHER *(* ossl_EVP_cipher_func)(void)
static void ResourceOwnerForgetOSSLCipher(ResourceOwner owner, OSSLCipher *od)
static unsigned gen_ossl_key_size(PX_Cipher *c)
static int ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static const struct ossl_cipher ossl_des3_ecb
static void ResOwnerReleaseOSSLCipher(Datum res)
static const struct ossl_cipher ossl_bf_cfb
struct OSSLDigest OSSLDigest
static int gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
static const struct ossl_cipher ossl_cast_cbc
static const ResourceOwnerDesc osslcipher_resowner_desc
static int gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
static void gen_ossl_free(PX_Cipher *c)
static const struct ossl_cipher ossl_des_cbc
static void digest_reset(PX_MD *h)
static void ResOwnerReleaseOSSLDigest(Datum res)
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static unsigned gen_ossl_iv_size(PX_Cipher *c)
int px_find_cipher(const char *name, PX_Cipher **res)
static const struct ossl_cipher ossl_bf_ecb
static PX_Alias ossl_aliases[]
static const struct ossl_cipher ossl_bf_cbc
static const struct ossl_cipher_lookup ossl_cipher_types[]
static void free_openssl_digest(OSSLDigest *digest)
static const struct ossl_cipher ossl_cast_ecb
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static unsigned digest_block_size(PX_MD *h)
static const struct ossl_cipher ossl_aes_cbc
static int ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static void digest_free(PX_MD *h)
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
static void ResourceOwnerRememberOSSLCipher(ResourceOwner owner, OSSLCipher *od)
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
int builtin_crypto_enabled
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
const char * px_resolve_alias(const PX_Alias *list, const char *name)
#define PXE_DECRYPT_FAILED
#define PXE_ENCRYPT_FAILED
ResourceOwner CurrentResourceOwner
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerEnlarge(ResourceOwner owner)
@ RESOURCE_RELEASE_BEFORE_LOCKS
#define RELEASE_PRIO_FIRST
const struct ossl_cipher * ciph
const EVP_CIPHER * evp_ciph
const struct ossl_cipher * ciph
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
ossl_EVP_cipher_func cipher_func
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
unsigned(* result_size)(PX_MD *h)
unsigned(* block_size)(PX_MD *h)
void(* finish)(PX_MD *h, uint8 *dst)