PostgreSQL Source Code: contrib/pgcrypto/openssl.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
33
34#include <openssl/crypto.h>
35#include <openssl/evp.h>
36#include <openssl/err.h>
37#include <openssl/rand.h>
38
39#include "px.h"
42
43
44
45
46#define MAX_KEY (512/8)
47#define MAX_IV (128/8)
48
49
50
51
52
53
54
55
56
58{
61
64
65
67
69{
70 .name = "pgcrypto OpenSSL digest handle",
74 .DebugPrint = NULL,
75};
76
77
78static inline void
80{
82}
83static inline void
85{
87}
88
89static void
91{
92 EVP_MD_CTX_destroy(digest->ctx);
93 if (digest->owner != NULL)
96}
97
98static unsigned
100{
102 int result = EVP_MD_CTX_size(digest->ctx);
103
104 if (result < 0)
105 elog(ERROR, "EVP_MD_CTX_size() failed");
106
107 return result;
108}
109
110static unsigned
112{
114 int result = EVP_MD_CTX_block_size(digest->ctx);
115
116 if (result < 0)
117 elog(ERROR, "EVP_MD_CTX_block_size() failed");
118
119 return result;
120}
121
122static void
124{
126
127 if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
128 elog(ERROR, "EVP_DigestInit_ex() failed");
129}
130
131static void
133{
135
136 if (!EVP_DigestUpdate(digest->ctx, data, dlen))
137 elog(ERROR, "EVP_DigestUpdate() failed");
138}
139
140static void
142{
144
145 if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
146 elog(ERROR, "EVP_DigestFinal_ex() failed");
147}
148
149static void
151{
153
156}
157
158
159
160int
162{
163 const EVP_MD *md;
164 EVP_MD_CTX *ctx;
167
168 md = EVP_get_digestbyname(name);
169 if (md == NULL)
171
173
174
175
176
177
178
180
181 ctx = EVP_MD_CTX_create();
182 if (!ctx)
183 {
186 }
187 if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
188 {
189 EVP_MD_CTX_destroy(ctx);
192 }
193
194 digest->algo = md;
195 digest->ctx = ctx;
198
199
200 h = palloc(sizeof(*h));
208
209 *res = h;
210 return 0;
211}
212
213
214
215static void
217{
219
220 digest->owner = NULL;
222}
223
224
225
226
227
228
229
230
231
232
233
234typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);
235
236
237
238
240{
245};
246
247
248
249
250
251
252
253
255{
263
266
267
269
271{
272 .name = "pgcrypto OpenSSL cipher handle",
276 .DebugPrint = NULL,
277};
278
279
280static inline void
282{
284}
285static inline void
287{
289}
290
291static void
293{
294 EVP_CIPHER_CTX_free(od->evp_ctx);
295 if (od->owner != NULL)
298}
299
300
301
302static unsigned
304{
306
308}
309
310static unsigned
312{
314
316}
317
318static unsigned
320{
321 unsigned ivlen;
323
325 return ivlen;
326}
327
328static void
330{
332
335}
336
337static int
339 uint8 *res, unsigned *rlen)
340{
342 int outlen,
343 outlen2;
344
345 if (!od->init)
346 {
347 if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, 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))
355 od->init = true;
356 }
357
358 if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
360 if (!EVP_DecryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
362 *rlen = outlen + outlen2;
363
364 return 0;
365}
366
367static int
369 uint8 *res, unsigned *rlen)
370{
372 int outlen,
373 outlen2;
374
375 if (!od->init)
376 {
377 if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
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))
385 od->init = true;
386 }
387
388 if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
390 if (!EVP_EncryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
392 *rlen = outlen + outlen2;
393
394 return 0;
395}
396
397
398
399
400
401
402
403
404static int
406{
407 static const uint8 key[56] = {
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
414 };
415
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;
420 int outlen;
421 int status = 0;
422
423
424 evp_ctx = EVP_CIPHER_CTX_new();
425 if (!evp_ctx)
426 return 0;
427 if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))
428 goto leave;
429 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))
430 goto leave;
431 if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL))
432 goto leave;
433
434 if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8))
435 goto leave;
436
437 if (memcmp(out, res, 8) != 0)
438 goto leave;
439
440 status = 1;
441
442leave:
443 EVP_CIPHER_CTX_free(evp_ctx);
444 return status;
445}
446
447static int
449{
452 static int bf_is_strong = -1;
453
454
455
456
457
458
459
460 if (bf_is_strong == -1)
462
463 if (!bf_is_strong && klen > 16)
465
466
467 od->klen = klen;
468 memcpy(od->key, key, klen);
469
470 if (iv)
471 memcpy(od->iv, iv, bs);
472 else
473 memset(od->iv, 0, bs);
474 return 0;
475}
476
477
478
479static int
481{
484
485 od->klen = 8;
486 memset(od->key, 0, 8);
487 memcpy(od->key, key, klen > 8 ? 8 : klen);
488
489 if (iv)
490 memcpy(od->iv, iv, bs);
491 else
492 memset(od->iv, 0, bs);
493 return 0;
494}
495
496
497
498static int
500{
503
504 od->klen = 24;
505 memset(od->key, 0, 24);
506 memcpy(od->key, key, klen > 24 ? 24 : klen);
507
508 if (iv)
509 memcpy(od->iv, iv, bs);
510 else
511 memset(od->iv, 0, bs);
512 return 0;
513}
514
515
516
517static int
519{
522
523 od->klen = klen;
524 memcpy(od->key, key, klen);
525
526 if (iv)
527 memcpy(od->iv, iv, bs);
528 else
529 memset(od->iv, 0, bs);
530 return 0;
531}
532
533
534
535static int
537{
540
541 if (klen <= 128 / 8)
542 od->klen = 128 / 8;
543 else if (klen <= 192 / 8)
544 od->klen = 192 / 8;
545 else if (klen <= 256 / 8)
546 od->klen = 256 / 8;
547 else
549
550 memcpy(od->key, key, klen);
551
552 if (iv)
553 memcpy(od->iv, iv, bs);
554 else
555 memset(od->iv, 0, bs);
556
557 return 0;
558}
559
560static int
562{
565
568 return err;
569
570 switch (od->klen)
571 {
572 case 128 / 8:
573 od->evp_ciph = EVP_aes_128_ecb();
574 break;
575 case 192 / 8:
576 od->evp_ciph = EVP_aes_192_ecb();
577 break;
578 case 256 / 8:
579 od->evp_ciph = EVP_aes_256_ecb();
580 break;
581 default:
582
584 break;
585 }
586
587 return err;
588}
589
590static int
592{
595
598 return err;
599
600 switch (od->klen)
601 {
602 case 128 / 8:
603 od->evp_ciph = EVP_aes_128_cbc();
604 break;
605 case 192 / 8:
606 od->evp_ciph = EVP_aes_192_cbc();
607 break;
608 case 256 / 8:
609 od->evp_ciph = EVP_aes_256_cbc();
610 break;
611 default:
612
614 break;
615 }
616
617 return err;
618}
619
620static int
622{
625
628 return err;
629
630 switch (od->klen)
631 {
632 case 128 / 8:
633 od->evp_ciph = EVP_aes_128_cfb();
634 break;
635 case 192 / 8:
636 od->evp_ciph = EVP_aes_192_cfb();
637 break;
638 case 256 / 8:
639 od->evp_ciph = EVP_aes_256_cfb();
640 break;
641 default:
642
644 break;
645 }
646
647 return err;
648}
649
650
651
652
653
655 {"bf", "bf-cbc"},
656 {"blowfish", "bf-cbc"},
657 {"blowfish-cbc", "bf-cbc"},
658 {"blowfish-ecb", "bf-ecb"},
659 {"blowfish-cfb", "bf-cfb"},
660 {"des", "des-cbc"},
661 {"3des", "des3-cbc"},
662 {"3des-ecb", "des3-ecb"},
663 {"3des-cbc", "des3-cbc"},
664 {"cast5", "cast5-cbc"},
665 {"aes", "aes-cbc"},
666 {"rijndael", "aes-cbc"},
667 {"rijndael-cbc", "aes-cbc"},
668 {"rijndael-ecb", "aes-ecb"},
669 {"rijndael-cfb", "aes-cfb"},
670 {NULL}
671};
672
675 EVP_bf_cbc,
676 64 / 8, 448 / 8
677};
678
681 EVP_bf_ecb,
682 64 / 8, 448 / 8
683};
684
687 EVP_bf_cfb,
688 64 / 8, 448 / 8
689};
690
693 EVP_des_ecb,
694 64 / 8, 64 / 8
695};
696
699 EVP_des_cbc,
700 64 / 8, 64 / 8
701};
702
705 EVP_des_ede3_ecb,
706 64 / 8, 192 / 8
707};
708
711 EVP_des_ede3_cbc,
712 64 / 8, 192 / 8
713};
714
717 EVP_cast5_ecb,
718 64 / 8, 128 / 8
719};
720
723 EVP_cast5_cbc,
724 64 / 8, 128 / 8
725};
726
729 NULL,
730
731 128 / 8, 256 / 8
732};
733
736 NULL,
737
738 128 / 8, 256 / 8
739};
740
743 NULL,
744
745 128 / 8, 256 / 8
746};
747
748
749
750
752{
755};
756
770 {NULL}
771};
772
773
774
775int
777{
780 EVP_CIPHER_CTX *ctx;
782
785 if (strcmp(i->name, name) == 0)
786 break;
787 if (i->name == NULL)
789
791
792
793
794
795
796
799
800
801 ctx = EVP_CIPHER_CTX_new();
802 if (!ctx)
803 {
806 }
807
811
812 if (i->ciph->cipher_func)
813 od->evp_ciph = i->ciph->cipher_func();
814
815
824 c->ptr = od;
825
826 *res = c;
827 return 0;
828}
829
830
831
832static void
834{
836}
837
838
839
840
841
842
843bool
845{
846 int fips_enabled = 0;
847
848
849
850
851
852
853
854
855 fips_enabled =
856#if OPENSSL_VERSION_NUMBER >= 0x30000000L
857 EVP_default_properties_is_fips_enabled(NULL);
858#else
859 FIPS_mode();
860#endif
861
862 return (fips_enabled == 1);
863}
864
865
866
867
868
869
870
871
872
873void
875{
877 return;
878
881 errmsg("use of built-in crypto functions is disabled"));
882
884
887 errmsg("use of non-FIPS validated crypto not allowed when OpenSSL is in FIPS mode"));
888}
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
Assert(PointerIsAligned(start, uint64))
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 struct ossl_cipher ossl_aes_cfb
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 int ossl_aes_cfb_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)