PostgreSQL Source Code: contrib/pgcrypto/openssl.c Source File

PostgreSQL Source Code git master
openssl.c
Go to the documentation of this file.
1/*
2 * openssl.c
3 * Wrapper for OpenSSL library.
4 *
5 * Copyright (c) 2001 Marko Kreen
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * contrib/pgcrypto/openssl.c
30 */
31
32#include "postgres.h"
33
34#include <openssl/crypto.h>
35#include <openssl/evp.h>
36#include <openssl/err.h>
37#include <openssl/rand.h>
38
39#include "px.h"
40#include "utils/memutils.h"
41#include "utils/resowner.h"
42
43/*
44 * Max lengths we might want to handle.
45 */
46 #define MAX_KEY (512/8)
47 #define MAX_IV (128/8)
48
49/*
50 * Hashes
51 */
52
53/*
54 * To make sure we don't leak OpenSSL handles, we use the ResourceOwner
55 * mechanism to free them on abort.
56 */
57 typedef struct OSSLDigest
58{
59 const EVP_MD *algo;
60 EVP_MD_CTX *ctx;
61
62 ResourceOwner owner;
63 } OSSLDigest;
64
65/* ResourceOwner callbacks to hold OpenSSL digest handles */
66static void ResOwnerReleaseOSSLDigest(Datum res);
67
68 static const ResourceOwnerDesc ossldigest_resowner_desc =
69{
70 .name = "pgcrypto OpenSSL digest handle",
71 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
72 .release_priority = RELEASE_PRIO_FIRST,
73 .ReleaseResource = ResOwnerReleaseOSSLDigest,
74 .DebugPrint = NULL, /* default message is fine */
75};
76
77/* Convenience wrappers over ResourceOwnerRemember/Forget */
78static inline void
79 ResourceOwnerRememberOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
80{
81 ResourceOwnerRemember(owner, PointerGetDatum(digest), &ossldigest_resowner_desc);
82}
83static inline void
84 ResourceOwnerForgetOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
85{
86 ResourceOwnerForget(owner, PointerGetDatum(digest), &ossldigest_resowner_desc);
87}
88
89static void
90 free_openssl_digest(OSSLDigest *digest)
91{
92 EVP_MD_CTX_destroy(digest->ctx);
93 if (digest->owner != NULL)
94 ResourceOwnerForgetOSSLDigest(digest->owner, digest);
95 pfree(digest);
96}
97
98static unsigned
99 digest_result_size(PX_MD *h)
100{
101 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
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
111 digest_block_size(PX_MD *h)
112{
113 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
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
123 digest_reset(PX_MD *h)
124{
125 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
126
127 if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
128 elog(ERROR, "EVP_DigestInit_ex() failed");
129}
130
131static void
132 digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
133{
134 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
135
136 if (!EVP_DigestUpdate(digest->ctx, data, dlen))
137 elog(ERROR, "EVP_DigestUpdate() failed");
138}
139
140static void
141 digest_finish(PX_MD *h, uint8 *dst)
142{
143 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
144
145 if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
146 elog(ERROR, "EVP_DigestFinal_ex() failed");
147}
148
149static void
150 digest_free(PX_MD *h)
151{
152 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
153
154 free_openssl_digest(digest);
155 pfree(h);
156}
157
158/* PUBLIC functions */
159
160int
161 px_find_digest(const char *name, PX_MD **res)
162{
163 const EVP_MD *md;
164 EVP_MD_CTX *ctx;
165 PX_MD *h;
166 OSSLDigest *digest;
167
168 md = EVP_get_digestbyname(name);
169 if (md == NULL)
170 return PXE_NO_HASH;
171
172 ResourceOwnerEnlarge(CurrentResourceOwner);
173
174 /*
175 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
176 * The order is crucial, to make sure we don't leak anything on
177 * out-of-memory or other error.
178 */
179 digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
180
181 ctx = EVP_MD_CTX_create();
182 if (!ctx)
183 {
184 pfree(digest);
185 return PXE_CIPHER_INIT;
186 }
187 if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
188 {
189 EVP_MD_CTX_destroy(ctx);
190 pfree(digest);
191 return PXE_CIPHER_INIT;
192 }
193
194 digest->algo = md;
195 digest->ctx = ctx;
196 digest->owner = CurrentResourceOwner;
197 ResourceOwnerRememberOSSLDigest(digest->owner, digest);
198
199 /* The PX_MD object is allocated in the current memory context. */
200 h = palloc(sizeof(*h));
201 h->result_size = digest_result_size;
202 h->block_size = digest_block_size;
203 h->reset = digest_reset;
204 h->update = digest_update;
205 h->finish = digest_finish;
206 h->free = digest_free;
207 h->p.ptr = digest;
208
209 *res = h;
210 return 0;
211}
212
213/* ResourceOwner callbacks for OSSLDigest */
214
215static void
216 ResOwnerReleaseOSSLDigest(Datum res)
217{
218 OSSLDigest *digest = (OSSLDigest *) DatumGetPointer(res);
219
220 digest->owner = NULL;
221 free_openssl_digest(digest);
222}
223
224/*
225 * Ciphers
226 *
227 * We use OpenSSL's EVP* family of functions for these.
228 */
229
230/*
231 * prototype for the EVP functions that return an algorithm, e.g.
232 * EVP_aes_128_cbc().
233 */
234 typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);
235
236/*
237 * ossl_cipher contains the static information about each cipher.
238 */
239 struct ossl_cipher
240{
241 int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
242 ossl_EVP_cipher_func cipher_func;
243 int block_size;
244 int max_key_size;
245};
246
247/*
248 * OSSLCipher contains the state for using a cipher. A separate OSSLCipher
249 * object is allocated in each px_find_cipher() call.
250 *
251 * To make sure we don't leak OpenSSL handles, we use the ResourceOwner
252 * mechanism to free them on abort.
253 */
254 typedef struct OSSLCipher
255{
256 EVP_CIPHER_CTX *evp_ctx;
257 const EVP_CIPHER *evp_ciph;
258 uint8 key[MAX_KEY];
259 uint8 iv[MAX_IV];
260 unsigned klen;
261 unsigned init;
262 const struct ossl_cipher *ciph;
263
264 ResourceOwner owner;
265 } OSSLCipher;
266
267/* ResourceOwner callbacks to hold OpenSSL cipher state */
268static void ResOwnerReleaseOSSLCipher(Datum res);
269
270 static const ResourceOwnerDesc osslcipher_resowner_desc =
271{
272 .name = "pgcrypto OpenSSL cipher handle",
273 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
274 .release_priority = RELEASE_PRIO_FIRST,
275 .ReleaseResource = ResOwnerReleaseOSSLCipher,
276 .DebugPrint = NULL, /* default message is fine */
277};
278
279/* Convenience wrappers over ResourceOwnerRemember/Forget */
280static inline void
281 ResourceOwnerRememberOSSLCipher(ResourceOwner owner, OSSLCipher *od)
282{
283 ResourceOwnerRemember(owner, PointerGetDatum(od), &osslcipher_resowner_desc);
284}
285static inline void
286 ResourceOwnerForgetOSSLCipher(ResourceOwner owner, OSSLCipher *od)
287{
288 ResourceOwnerForget(owner, PointerGetDatum(od), &osslcipher_resowner_desc);
289}
290
291static void
292 free_openssl_cipher(OSSLCipher *od)
293{
294 EVP_CIPHER_CTX_free(od->evp_ctx);
295 if (od->owner != NULL)
296 ResourceOwnerForgetOSSLCipher(od->owner, od);
297 pfree(od);
298}
299
300/* Common routines for all algorithms */
301
302static unsigned
303 gen_ossl_block_size(PX_Cipher *c)
304{
305 OSSLCipher *od = (OSSLCipher *) c->ptr;
306
307 return od->ciph->block_size;
308}
309
310static unsigned
311 gen_ossl_key_size(PX_Cipher *c)
312{
313 OSSLCipher *od = (OSSLCipher *) c->ptr;
314
315 return od->ciph->max_key_size;
316}
317
318static unsigned
319 gen_ossl_iv_size(PX_Cipher *c)
320{
321 unsigned ivlen;
322 OSSLCipher *od = (OSSLCipher *) c->ptr;
323
324 ivlen = od->ciph->block_size;
325 return ivlen;
326}
327
328static void
329 gen_ossl_free(PX_Cipher *c)
330{
331 OSSLCipher *od = (OSSLCipher *) c->ptr;
332
333 free_openssl_cipher(od);
334 pfree(c);
335}
336
337static int
338 gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
339 uint8 *res, unsigned *rlen)
340{
341 OSSLCipher *od = c->ptr;
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))
348 return PXE_CIPHER_INIT;
349 if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
350 return PXE_CIPHER_INIT;
351 if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
352 return PXE_CIPHER_INIT;
353 if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
354 return PXE_CIPHER_INIT;
355 od->init = true;
356 }
357
358 if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
359 return PXE_DECRYPT_FAILED;
360 if (!EVP_DecryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
361 return PXE_DECRYPT_FAILED;
362 *rlen = outlen + outlen2;
363
364 return 0;
365}
366
367static int
368 gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen,
369 uint8 *res, unsigned *rlen)
370{
371 OSSLCipher *od = c->ptr;
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))
378 return PXE_CIPHER_INIT;
379 if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))
380 return PXE_CIPHER_INIT;
381 if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
382 return PXE_CIPHER_INIT;
383 if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
384 return PXE_CIPHER_INIT;
385 od->init = true;
386 }
387
388 if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
389 return PXE_ENCRYPT_FAILED;
390 if (!EVP_EncryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))
391 return PXE_ENCRYPT_FAILED;
392 *rlen = outlen + outlen2;
393
394 return 0;
395}
396
397/* Blowfish */
398
399/*
400 * Check if strong crypto is supported. Some OpenSSL installations
401 * support only short keys and unfortunately BF_set_key does not return any
402 * error value. This function tests if is possible to use strong key.
403 */
404static int
405 bf_check_supported_key_len(void)
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};
418 uint8 out[8];
419 EVP_CIPHER_CTX *evp_ctx;
420 int outlen;
421 int status = 0;
422
423 /* encrypt with 448bits key and verify output */
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; /* Output does not match -> strong cipher is
439 * not supported */
440 status = 1;
441
442leave:
443 EVP_CIPHER_CTX_free(evp_ctx);
444 return status;
445}
446
447static int
448 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
449{
450 OSSLCipher *od = c->ptr;
451 unsigned bs = gen_ossl_block_size(c);
452 static int bf_is_strong = -1;
453
454 /*
455 * Test if key len is supported. BF_set_key silently cut large keys and it
456 * could be a problem when user transfer encrypted data from one server to
457 * another.
458 */
459
460 if (bf_is_strong == -1)
461 bf_is_strong = bf_check_supported_key_len();
462
463 if (!bf_is_strong && klen > 16)
464 return PXE_KEY_TOO_BIG;
465
466 /* Key len is supported. We can use it. */
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/* DES */
478
479static int
480 ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
481{
482 OSSLCipher *od = c->ptr;
483 unsigned bs = gen_ossl_block_size(c);
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/* DES3 */
497
498static int
499 ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
500{
501 OSSLCipher *od = c->ptr;
502 unsigned bs = gen_ossl_block_size(c);
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/* CAST5 */
516
517static int
518 ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
519{
520 OSSLCipher *od = c->ptr;
521 unsigned bs = gen_ossl_block_size(c);
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/* AES */
534
535static int
536 ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
537{
538 OSSLCipher *od = c->ptr;
539 unsigned bs = gen_ossl_block_size(c);
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
548 return PXE_KEY_TOO_BIG;
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
561 ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
562{
563 OSSLCipher *od = c->ptr;
564 int err;
565
566 err = ossl_aes_init(c, key, klen, iv);
567 if (err)
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 /* shouldn't happen */
583 err = PXE_CIPHER_INIT;
584 break;
585 }
586
587 return err;
588}
589
590static int
591 ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
592{
593 OSSLCipher *od = c->ptr;
594 int err;
595
596 err = ossl_aes_init(c, key, klen, iv);
597 if (err)
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 /* shouldn't happen */
613 err = PXE_CIPHER_INIT;
614 break;
615 }
616
617 return err;
618}
619
620static int
621 ossl_aes_cfb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
622{
623 OSSLCipher *od = c->ptr;
624 int err;
625
626 err = ossl_aes_init(c, key, klen, iv);
627 if (err)
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 /* shouldn't happen */
643 err = PXE_CIPHER_INIT;
644 break;
645 }
646
647 return err;
648}
649
650/*
651 * aliases
652 */
653
654 static PX_Alias ossl_aliases[] = {
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
673 static const struct ossl_cipher ossl_bf_cbc = {
674 bf_init,
675 EVP_bf_cbc,
676 64 / 8, 448 / 8
677};
678
679 static const struct ossl_cipher ossl_bf_ecb = {
680 bf_init,
681 EVP_bf_ecb,
682 64 / 8, 448 / 8
683};
684
685 static const struct ossl_cipher ossl_bf_cfb = {
686 bf_init,
687 EVP_bf_cfb,
688 64 / 8, 448 / 8
689};
690
691 static const struct ossl_cipher ossl_des_ecb = {
692 ossl_des_init,
693 EVP_des_ecb,
694 64 / 8, 64 / 8
695};
696
697 static const struct ossl_cipher ossl_des_cbc = {
698 ossl_des_init,
699 EVP_des_cbc,
700 64 / 8, 64 / 8
701};
702
703 static const struct ossl_cipher ossl_des3_ecb = {
704 ossl_des3_init,
705 EVP_des_ede3_ecb,
706 64 / 8, 192 / 8
707};
708
709 static const struct ossl_cipher ossl_des3_cbc = {
710 ossl_des3_init,
711 EVP_des_ede3_cbc,
712 64 / 8, 192 / 8
713};
714
715 static const struct ossl_cipher ossl_cast_ecb = {
716 ossl_cast_init,
717 EVP_cast5_ecb,
718 64 / 8, 128 / 8
719};
720
721 static const struct ossl_cipher ossl_cast_cbc = {
722 ossl_cast_init,
723 EVP_cast5_cbc,
724 64 / 8, 128 / 8
725};
726
727 static const struct ossl_cipher ossl_aes_ecb = {
728 ossl_aes_ecb_init,
729 NULL, /* EVP_aes_XXX_ecb(), determined in init
730 * function */
731 128 / 8, 256 / 8
732};
733
734 static const struct ossl_cipher ossl_aes_cbc = {
735 ossl_aes_cbc_init,
736 NULL, /* EVP_aes_XXX_cbc(), determined in init
737 * function */
738 128 / 8, 256 / 8
739};
740
741 static const struct ossl_cipher ossl_aes_cfb = {
742 ossl_aes_cfb_init,
743 NULL, /* EVP_aes_XXX_cfb(), determined in init
744 * function */
745 128 / 8, 256 / 8
746};
747
748/*
749 * Special handlers
750 */
751 struct ossl_cipher_lookup
752{
753 const char *name;
754 const struct ossl_cipher *ciph;
755};
756
757 static const struct ossl_cipher_lookup ossl_cipher_types[] = {
758 {"bf-cbc", &ossl_bf_cbc},
759 {"bf-ecb", &ossl_bf_ecb},
760 {"bf-cfb", &ossl_bf_cfb},
761 {"des-ecb", &ossl_des_ecb},
762 {"des-cbc", &ossl_des_cbc},
763 {"des3-ecb", &ossl_des3_ecb},
764 {"des3-cbc", &ossl_des3_cbc},
765 {"cast5-ecb", &ossl_cast_ecb},
766 {"cast5-cbc", &ossl_cast_cbc},
767 {"aes-ecb", &ossl_aes_ecb},
768 {"aes-cbc", &ossl_aes_cbc},
769 {"aes-cfb", &ossl_aes_cfb},
770 {NULL}
771};
772
773/* PUBLIC functions */
774
775int
776 px_find_cipher(const char *name, PX_Cipher **res)
777{
778 const struct ossl_cipher_lookup *i;
779 PX_Cipher *c = NULL;
780 EVP_CIPHER_CTX *ctx;
781 OSSLCipher *od;
782
783 name = px_resolve_alias(ossl_aliases, name);
784 for (i = ossl_cipher_types; i->name; i++)
785 if (strcmp(i->name, name) == 0)
786 break;
787 if (i->name == NULL)
788 return PXE_NO_CIPHER;
789
790 ResourceOwnerEnlarge(CurrentResourceOwner);
791
792 /*
793 * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
794 * The order is crucial, to make sure we don't leak anything on
795 * out-of-memory or other error.
796 */
797 od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
798 od->ciph = i->ciph;
799
800 /* Allocate an EVP_CIPHER_CTX object. */
801 ctx = EVP_CIPHER_CTX_new();
802 if (!ctx)
803 {
804 pfree(od);
805 return PXE_CIPHER_INIT;
806 }
807
808 od->evp_ctx = ctx;
809 od->owner = CurrentResourceOwner;
810 ResourceOwnerRememberOSSLCipher(od->owner, od);
811
812 if (i->ciph->cipher_func)
813 od->evp_ciph = i->ciph->cipher_func();
814
815 /* The PX_Cipher is allocated in current memory context */
816 c = palloc(sizeof(*c));
817 c->block_size = gen_ossl_block_size;
818 c->key_size = gen_ossl_key_size;
819 c->iv_size = gen_ossl_iv_size;
820 c->free = gen_ossl_free;
821 c->init = od->ciph->init;
822 c->encrypt = gen_ossl_encrypt;
823 c->decrypt = gen_ossl_decrypt;
824 c->ptr = od;
825
826 *res = c;
827 return 0;
828}
829
830/* ResourceOwner callbacks for OSSLCipher */
831
832static void
833 ResOwnerReleaseOSSLCipher(Datum res)
834{
835 free_openssl_cipher((OSSLCipher *) DatumGetPointer(res));
836}
837
838/*
839 * CheckFIPSMode
840 *
841 * Returns the FIPS mode of the underlying OpenSSL installation.
842 */
843bool
844 CheckFIPSMode(void)
845{
846 int fips_enabled = 0;
847
848 /*
849 * EVP_default_properties_is_fips_enabled was added in OpenSSL 3.0, before
850 * that FIPS_mode() was used to test for FIPS being enabled. The last
851 * upstream OpenSSL version before 3.0 which supported FIPS was 1.0.2, but
852 * there are forks of 1.1.1 which are FIPS validated so we still need to
853 * test with FIPS_mode() even though we don't support 1.0.2.
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 * CheckBuiltinCryptoMode
867 *
868 * Function for erroring out in case built-in crypto is executed when the user
869 * has disabled it. If builtin_crypto_enabled is set to BC_OFF or BC_FIPS and
870 * OpenSSL is operating in FIPS mode the function will error out, else the
871 * query executing built-in crypto can proceed.
872 */
873void
874 CheckBuiltinCryptoMode(void)
875{
876 if (builtin_crypto_enabled == BC_ON)
877 return;
878
879 if (builtin_crypto_enabled == BC_OFF)
880 ereport(ERROR,
881 errmsg("use of built-in crypto functions is disabled"));
882
883 Assert(builtin_crypto_enabled == BC_FIPS);
884
885 if (CheckFIPSMode() == true)
886 ereport(ERROR,
887 errmsg("use of non-FIPS validated crypto not allowed when OpenSSL is in FIPS mode"));
888}
uint8_t uint8
Definition: c.h:536
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
void err(int eval, const char *fmt,...)
Definition: err.c:43
Assert(PointerIsAligned(start, uint64))
i
int i
Definition: isn.c:77
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
void pfree(void *pointer)
Definition: mcxt.c:1594
MemoryContext TopMemoryContext
Definition: mcxt.c:166
void * palloc(Size size)
Definition: mcxt.c:1365
static unsigned gen_ossl_block_size(PX_Cipher *c)
Definition: openssl.c:303
int px_find_digest(const char *name, PX_MD **res)
Definition: openssl.c:161
void CheckBuiltinCryptoMode(void)
Definition: openssl.c:874
static const struct ossl_cipher ossl_des_ecb
Definition: openssl.c:691
static const struct ossl_cipher ossl_des3_cbc
Definition: openssl.c:709
static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: openssl.c:132
static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:448
static int bf_check_supported_key_len(void)
Definition: openssl.c:405
static void ResourceOwnerForgetOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
Definition: openssl.c:84
static unsigned digest_result_size(PX_MD *h)
Definition: openssl.c:99
static const struct ossl_cipher ossl_aes_ecb
Definition: openssl.c:727
static void ResourceOwnerRememberOSSLDigest(ResourceOwner owner, OSSLDigest *digest)
Definition: openssl.c:79
#define MAX_KEY
Definition: openssl.c:46
bool CheckFIPSMode(void)
Definition: openssl.c:844
static void digest_finish(PX_MD *h, uint8 *dst)
Definition: openssl.c:141
struct OSSLCipher OSSLCipher
static const struct ossl_cipher ossl_aes_cfb
Definition: openssl.c:741
static const ResourceOwnerDesc ossldigest_resowner_desc
Definition: openssl.c:68
static void free_openssl_cipher(OSSLCipher *od)
Definition: openssl.c:292
const EVP_CIPHER *(* ossl_EVP_cipher_func)(void)
Definition: openssl.c:234
static void ResourceOwnerForgetOSSLCipher(ResourceOwner owner, OSSLCipher *od)
Definition: openssl.c:286
static unsigned gen_ossl_key_size(PX_Cipher *c)
Definition: openssl.c:311
static int ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:561
static const struct ossl_cipher ossl_des3_ecb
Definition: openssl.c:703
static void ResOwnerReleaseOSSLCipher(Datum res)
Definition: openssl.c:833
static const struct ossl_cipher ossl_bf_cfb
Definition: openssl.c:685
struct OSSLDigest OSSLDigest
static int gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: openssl.c:368
static const struct ossl_cipher ossl_cast_cbc
Definition: openssl.c:721
static const ResourceOwnerDesc osslcipher_resowner_desc
Definition: openssl.c:270
static int gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)
Definition: openssl.c:338
static void gen_ossl_free(PX_Cipher *c)
Definition: openssl.c:329
static const struct ossl_cipher ossl_des_cbc
Definition: openssl.c:697
static void digest_reset(PX_MD *h)
Definition: openssl.c:123
static void ResOwnerReleaseOSSLDigest(Datum res)
Definition: openssl.c:216
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:518
static unsigned gen_ossl_iv_size(PX_Cipher *c)
Definition: openssl.c:319
int px_find_cipher(const char *name, PX_Cipher **res)
Definition: openssl.c:776
static const struct ossl_cipher ossl_bf_ecb
Definition: openssl.c:679
static PX_Alias ossl_aliases[]
Definition: openssl.c:654
static const struct ossl_cipher ossl_bf_cbc
Definition: openssl.c:673
static const struct ossl_cipher_lookup ossl_cipher_types[]
Definition: openssl.c:757
static void free_openssl_digest(OSSLDigest *digest)
Definition: openssl.c:90
#define MAX_IV
Definition: openssl.c:47
static const struct ossl_cipher ossl_cast_ecb
Definition: openssl.c:715
static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:536
static int ossl_aes_cfb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:621
static unsigned digest_block_size(PX_MD *h)
Definition: openssl.c:111
static const struct ossl_cipher ossl_aes_cbc
Definition: openssl.c:734
static int ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:591
static void digest_free(PX_MD *h)
Definition: openssl.c:150
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:499
static void ResourceOwnerRememberOSSLCipher(ResourceOwner owner, OSSLCipher *od)
Definition: openssl.c:281
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:480
const void * data
int builtin_crypto_enabled
Definition: pgcrypto.c:62
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
c
char * c
Definition: preproc-cursor.c:31
const char * px_resolve_alias(const PX_Alias *list, const char *name)
Definition: px.c:129
#define PXE_DECRYPT_FAILED
Definition: px.h:64
#define PXE_CIPHER_INIT
Definition: px.h:54
#define PXE_ENCRYPT_FAILED
Definition: px.h:65
@ BC_ON
Definition: px.h:94
@ BC_OFF
Definition: px.h:95
@ BC_FIPS
Definition: px.h:96
#define PXE_NO_HASH
Definition: px.h:48
#define PXE_NO_CIPHER
Definition: px.h:49
#define PXE_KEY_TOO_BIG
Definition: px.h:53
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:561
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:521
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:449
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
#define RELEASE_PRIO_FIRST
Definition: resowner.h:80
unsigned klen
Definition: openssl.c:260
const struct ossl_cipher * ciph
Definition: openssl.c:262
uint8 iv[MAX_IV]
Definition: openssl.c:259
ResourceOwner owner
Definition: openssl.c:264
unsigned init
Definition: openssl.c:261
EVP_CIPHER_CTX * evp_ctx
Definition: openssl.c:256
uint8 key[MAX_KEY]
Definition: openssl.c:258
const EVP_CIPHER * evp_ciph
Definition: openssl.c:257
EVP_MD_CTX * ctx
Definition: openssl.c:60
const EVP_MD * algo
Definition: openssl.c:59
ResourceOwner owner
Definition: openssl.c:62
const char * name
Definition: resowner.h:93
const char * name
Definition: openssl.c:753
const struct ossl_cipher * ciph
Definition: openssl.c:754
int block_size
Definition: openssl.c:243
int max_key_size
Definition: openssl.c:244
int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
Definition: openssl.c:241
ossl_EVP_cipher_func cipher_func
Definition: openssl.c:242
Definition: px.h:124
Definition: px.h:149
Definition: px.h:108
void(* free)(PX_MD *h)
Definition: px.h:114
void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)
Definition: px.h:112
unsigned(* result_size)(PX_MD *h)
Definition: px.h:109
union px_digest::@8 p
void(* reset)(PX_MD *h)
Definition: px.h:111
unsigned(* block_size)(PX_MD *h)
Definition: px.h:110
void * ptr
Definition: px.h:119
void(* finish)(PX_MD *h, uint8 *dst)
Definition: px.h:113
const char * name

AltStyle によって変換されたページ (->オリジナル) /