3 * Wrapper for OpenSSL library.
5 * Copyright (c) 2001 Marko Kreen
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
29 * contrib/pgcrypto/openssl.c
34 #include <openssl/evp.h>
35 #include <openssl/err.h>
36 #include <openssl/rand.h>
39 #include "utils/memutils.h"
40 #include "utils/resowner.h"
43 * Max lengths we might want to handle.
45 #define MAX_KEY (512/8)
46 #define MAX_IV (128/8)
53 * To make sure we don't leak OpenSSL handles, we use the ResourceOwner
54 * mechanism to free them on abort.
56 typedef struct OSSLDigest
64 /* ResourceOwner callbacks to hold OpenSSL digest handles */
65 static void ResOwnerReleaseOSSLDigest(Datum res
);
67 static const ResourceOwnerDesc ossldigest_resowner_desc
=
69 .name
= "pgcrypto OpenSSL digest handle",
70 .release_phase
= RESOURCE_RELEASE_BEFORE_LOCKS
,
71 .release_priority
= RELEASE_PRIO_FIRST
,
72 .ReleaseResource
= ResOwnerReleaseOSSLDigest
,
73 .DebugPrint
= NULL
, /* default message is fine */
76 /* Convenience wrappers over ResourceOwnerRemember/Forget */
78 ResourceOwnerRememberOSSLDigest(ResourceOwner owner
, OSSLDigest
*digest
)
80 ResourceOwnerRemember(owner
, PointerGetDatum(digest
), &ossldigest_resowner_desc
);
83 ResourceOwnerForgetOSSLDigest(ResourceOwner owner
, OSSLDigest
*digest
)
85 ResourceOwnerForget(owner
, PointerGetDatum(digest
), &ossldigest_resowner_desc
);
89 free_openssl_digest(OSSLDigest
*digest
)
91 EVP_MD_CTX_destroy(digest
->ctx
);
92 if (digest
->owner
!= NULL
)
93 ResourceOwnerForgetOSSLDigest(digest
->owner
, digest
);
98 digest_result_size(PX_MD
*h
)
100 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
101 int result
= EVP_MD_CTX_size(digest
->ctx
);
104 elog(ERROR
, "EVP_MD_CTX_size() failed");
110 digest_block_size(PX_MD
*h
)
112 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
113 int result
= EVP_MD_CTX_block_size(digest
->ctx
);
116 elog(ERROR
, "EVP_MD_CTX_block_size() failed");
122 digest_reset(PX_MD
*h
)
124 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
126 if (!EVP_DigestInit_ex(digest
->ctx
, digest
->algo
, NULL
))
127 elog(ERROR
, "EVP_DigestInit_ex() failed");
131 digest_update(PX_MD
*h
, const uint8
*data
, unsigned dlen
)
133 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
135 if (!EVP_DigestUpdate(digest
->ctx
, data
, dlen
))
136 elog(ERROR
, "EVP_DigestUpdate() failed");
140 digest_finish(PX_MD
*h
, uint8
*dst
)
142 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
144 if (!EVP_DigestFinal_ex(digest
->ctx
, dst
, NULL
))
145 elog(ERROR
, "EVP_DigestFinal_ex() failed");
149 digest_free(PX_MD
*h
)
151 OSSLDigest
*digest
= (OSSLDigest
*) h
->p
.ptr
;
153 free_openssl_digest(digest
);
157 /* PUBLIC functions */
160 px_find_digest(const char *name
, PX_MD
**res
)
167 md
= EVP_get_digestbyname(name
);
171 ResourceOwnerEnlarge(CurrentResourceOwner
);
174 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
175 * The order is crucial, to make sure we don't leak anything on
176 * out-of-memory or other error.
178 digest
= MemoryContextAlloc(TopMemoryContext
, sizeof(*digest
));
180 ctx
= EVP_MD_CTX_create();
184 return PXE_CIPHER_INIT
;
186 if (EVP_DigestInit_ex(ctx
, md
, NULL
) == 0)
188 EVP_MD_CTX_destroy(ctx
);
190 return PXE_CIPHER_INIT
;
195 digest
->owner
= CurrentResourceOwner
;
196 ResourceOwnerRememberOSSLDigest(digest
->owner
, digest
);
198 /* The PX_MD object is allocated in the current memory context. */
199 h
= palloc(sizeof(*h
));
200 h
->result_size
= digest_result_size
;
201 h
->block_size
= digest_block_size
;
202 h
->reset
= digest_reset
;
203 h
->update
= digest_update
;
204 h
->finish
= digest_finish
;
205 h
->free
= digest_free
;
212 /* ResourceOwner callbacks for OSSLDigest */
215 ResOwnerReleaseOSSLDigest(Datum res
)
217 OSSLDigest
*digest
= (OSSLDigest
*) DatumGetPointer(res
);
219 digest
->owner
= NULL
;
220 free_openssl_digest(digest
);
226 * We use OpenSSL's EVP* family of functions for these.
230 * prototype for the EVP functions that return an algorithm, e.g.
233 typedef const EVP_CIPHER
*(*ossl_EVP_cipher_func
) (void);
236 * ossl_cipher contains the static information about each cipher.
240 int (*init
) (PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
);
241 ossl_EVP_cipher_func cipher_func
;
247 * OSSLCipher contains the state for using a cipher. A separate OSSLCipher
248 * object is allocated in each px_find_cipher() call.
250 * To make sure we don't leak OpenSSL handles, we use the ResourceOwner
251 * mechanism to free them on abort.
253 typedef struct OSSLCipher
255 EVP_CIPHER_CTX
*evp_ctx
;
256 const EVP_CIPHER
*evp_ciph
;
261 const struct ossl_cipher
*ciph
;
266 /* ResourceOwner callbacks to hold OpenSSL cipher state */
267 static void ResOwnerReleaseOSSLCipher(Datum res
);
269 static const ResourceOwnerDesc osslcipher_resowner_desc
=
271 .name
= "pgcrypto OpenSSL cipher handle",
272 .release_phase
= RESOURCE_RELEASE_BEFORE_LOCKS
,
273 .release_priority
= RELEASE_PRIO_FIRST
,
274 .ReleaseResource
= ResOwnerReleaseOSSLCipher
,
275 .DebugPrint
= NULL
, /* default message is fine */
278 /* Convenience wrappers over ResourceOwnerRemember/Forget */
280 ResourceOwnerRememberOSSLCipher(ResourceOwner owner
, OSSLCipher
*od
)
282 ResourceOwnerRemember(owner
, PointerGetDatum(od
), &osslcipher_resowner_desc
);
285 ResourceOwnerForgetOSSLCipher(ResourceOwner owner
, OSSLCipher
*od
)
287 ResourceOwnerForget(owner
, PointerGetDatum(od
), &osslcipher_resowner_desc
);
291 free_openssl_cipher(OSSLCipher
*od
)
293 EVP_CIPHER_CTX_free(od
->evp_ctx
);
294 if (od
->owner
!= NULL
)
295 ResourceOwnerForgetOSSLCipher(od
->owner
, od
);
299 /* Common routines for all algorithms */
302 gen_ossl_block_size(PX_Cipher
*c
)
304 OSSLCipher
*od
= (OSSLCipher
*) c
->ptr
;
306 return od
->ciph
->block_size
;
310 gen_ossl_key_size(PX_Cipher
*c
)
312 OSSLCipher
*od
= (OSSLCipher
*) c
->ptr
;
314 return od
->ciph
->max_key_size
;
318 gen_ossl_iv_size(PX_Cipher
*c
)
321 OSSLCipher
*od
= (OSSLCipher
*) c
->ptr
;
323 ivlen
= od
->ciph
->block_size
;
328 gen_ossl_free(PX_Cipher
*c
)
330 OSSLCipher
*od
= (OSSLCipher
*) c
->ptr
;
332 free_openssl_cipher(od
);
337 gen_ossl_decrypt(PX_Cipher
*c
, int padding
, const uint8
*data
, unsigned dlen
,
338 uint8
*res
, unsigned *rlen
)
340 OSSLCipher
*od
= c
->ptr
;
346 if (!EVP_DecryptInit_ex(od
->evp_ctx
, od
->evp_ciph
, NULL
, NULL
, NULL
))
347 return PXE_CIPHER_INIT
;
348 if (!EVP_CIPHER_CTX_set_padding(od
->evp_ctx
, padding
))
349 return PXE_CIPHER_INIT
;
350 if (!EVP_CIPHER_CTX_set_key_length(od
->evp_ctx
, od
->klen
))
351 return PXE_CIPHER_INIT
;
352 if (!EVP_DecryptInit_ex(od
->evp_ctx
, NULL
, NULL
, od
->key
, od
->iv
))
353 return PXE_CIPHER_INIT
;
357 if (!EVP_DecryptUpdate(od
->evp_ctx
, res
, &outlen
, data
, dlen
))
358 return PXE_DECRYPT_FAILED
;
359 if (!EVP_DecryptFinal_ex(od
->evp_ctx
, res
+ outlen
, &outlen2
))
360 return PXE_DECRYPT_FAILED
;
361 *rlen
= outlen
+ outlen2
;
367 gen_ossl_encrypt(PX_Cipher
*c
, int padding
, const uint8
*data
, unsigned dlen
,
368 uint8
*res
, unsigned *rlen
)
370 OSSLCipher
*od
= c
->ptr
;
376 if (!EVP_EncryptInit_ex(od
->evp_ctx
, od
->evp_ciph
, NULL
, NULL
, NULL
))
377 return PXE_CIPHER_INIT
;
378 if (!EVP_CIPHER_CTX_set_padding(od
->evp_ctx
, padding
))
379 return PXE_CIPHER_INIT
;
380 if (!EVP_CIPHER_CTX_set_key_length(od
->evp_ctx
, od
->klen
))
381 return PXE_CIPHER_INIT
;
382 if (!EVP_EncryptInit_ex(od
->evp_ctx
, NULL
, NULL
, od
->key
, od
->iv
))
383 return PXE_CIPHER_INIT
;
387 if (!EVP_EncryptUpdate(od
->evp_ctx
, res
, &outlen
, data
, dlen
))
388 return PXE_ENCRYPT_FAILED
;
389 if (!EVP_EncryptFinal_ex(od
->evp_ctx
, res
+ outlen
, &outlen2
))
390 return PXE_ENCRYPT_FAILED
;
391 *rlen
= outlen
+ outlen2
;
399 * Check if strong crypto is supported. Some OpenSSL installations
400 * support only short keys and unfortunately BF_set_key does not return any
401 * error value. This function tests if is possible to use strong key.
404 bf_check_supported_key_len(void)
406 static const uint8 key
[56] = {
407 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
408 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
409 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
410 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
411 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
412 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
415 static const uint8 data
[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
416 static const uint8 res
[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
418 EVP_CIPHER_CTX
*evp_ctx
;
422 /* encrypt with 448bits key and verify output */
423 evp_ctx
= EVP_CIPHER_CTX_new();
426 if (!EVP_EncryptInit_ex(evp_ctx
, EVP_bf_ecb(), NULL
, NULL
, NULL
))
428 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx
, 56))
430 if (!EVP_EncryptInit_ex(evp_ctx
, NULL
, NULL
, key
, NULL
))
433 if (!EVP_EncryptUpdate(evp_ctx
, out
, &outlen
, data
, 8))
436 if (memcmp(out
, res
, 8) != 0)
437 goto leave
; /* Output does not match -> strong cipher is
442 EVP_CIPHER_CTX_free(evp_ctx
);
447 bf_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
449 OSSLCipher
*od
= c
->ptr
;
450 unsigned bs
= gen_ossl_block_size(c
);
451 static int bf_is_strong
= -1;
454 * Test if key len is supported. BF_set_key silently cut large keys and it
455 * could be a problem when user transfer encrypted data from one server to
459 if (bf_is_strong
== -1)
460 bf_is_strong
= bf_check_supported_key_len();
462 if (!bf_is_strong
&& klen
> 16)
463 return PXE_KEY_TOO_BIG
;
465 /* Key len is supported. We can use it. */
467 memcpy(od
->key
, key
, klen
);
470 memcpy(od
->iv
, iv
, bs
);
472 memset(od
->iv
, 0, bs
);
479 ossl_des_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
481 OSSLCipher
*od
= c
->ptr
;
482 unsigned bs
= gen_ossl_block_size(c
);
485 memset(od
->key
, 0, 8);
486 memcpy(od
->key
, key
, klen
> 8 ? 8 : klen
);
489 memcpy(od
->iv
, iv
, bs
);
491 memset(od
->iv
, 0, bs
);
498 ossl_des3_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
500 OSSLCipher
*od
= c
->ptr
;
501 unsigned bs
= gen_ossl_block_size(c
);
504 memset(od
->key
, 0, 24);
505 memcpy(od
->key
, key
, klen
> 24 ? 24 : klen
);
508 memcpy(od
->iv
, iv
, bs
);
510 memset(od
->iv
, 0, bs
);
517 ossl_cast_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
519 OSSLCipher
*od
= c
->ptr
;
520 unsigned bs
= gen_ossl_block_size(c
);
523 memcpy(od
->key
, key
, klen
);
526 memcpy(od
->iv
, iv
, bs
);
528 memset(od
->iv
, 0, bs
);
535 ossl_aes_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
537 OSSLCipher
*od
= c
->ptr
;
538 unsigned bs
= gen_ossl_block_size(c
);
542 else if (klen
<= 192 / 8)
544 else if (klen
<= 256 / 8)
547 return PXE_KEY_TOO_BIG
;
549 memcpy(od
->key
, key
, klen
);
552 memcpy(od
->iv
, iv
, bs
);
554 memset(od
->iv
, 0, bs
);
560 ossl_aes_ecb_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
562 OSSLCipher
*od
= c
->ptr
;
565 err
= ossl_aes_init(c
, key
, klen
, iv
);
572 od
->evp_ciph
= EVP_aes_128_ecb();
575 od
->evp_ciph
= EVP_aes_192_ecb();
578 od
->evp_ciph
= EVP_aes_256_ecb();
581 /* shouldn't happen */
582 err
= PXE_CIPHER_INIT
;
590 ossl_aes_cbc_init(PX_Cipher
*c
, const uint8
*key
, unsigned klen
, const uint8
*iv
)
592 OSSLCipher
*od
= c
->ptr
;
595 err
= ossl_aes_init(c
, key
, klen
, iv
);
602 od
->evp_ciph
= EVP_aes_128_cbc();
605 od
->evp_ciph
= EVP_aes_192_cbc();
608 od
->evp_ciph
= EVP_aes_256_cbc();
611 /* shouldn't happen */
612 err
= PXE_CIPHER_INIT
;
623 static PX_Alias ossl_aliases
[] = {
625 {"blowfish", "bf-cbc"},
626 {"blowfish-cbc", "bf-cbc"},
627 {"blowfish-ecb", "bf-ecb"},
628 {"blowfish-cfb", "bf-cfb"},
630 {"3des", "des3-cbc"},
631 {"3des-ecb", "des3-ecb"},
632 {"3des-cbc", "des3-cbc"},
633 {"cast5", "cast5-cbc"},
635 {"rijndael", "aes-cbc"},
636 {"rijndael-cbc", "aes-cbc"},
637 {"rijndael-ecb", "aes-ecb"},
641 static const struct ossl_cipher ossl_bf_cbc
= {
647 static const struct ossl_cipher ossl_bf_ecb
= {
653 static const struct ossl_cipher ossl_bf_cfb
= {
659 static const struct ossl_cipher ossl_des_ecb
= {
665 static const struct ossl_cipher ossl_des_cbc
= {
671 static const struct ossl_cipher ossl_des3_ecb
= {
677 static const struct ossl_cipher ossl_des3_cbc
= {
683 static const struct ossl_cipher ossl_cast_ecb
= {
689 static const struct ossl_cipher ossl_cast_cbc
= {
695 static const struct ossl_cipher ossl_aes_ecb
= {
697 NULL
, /* EVP_aes_XXX_ecb(), determined in init
702 static const struct ossl_cipher ossl_aes_cbc
= {
704 NULL
, /* EVP_aes_XXX_cbc(), determined in init
712 struct ossl_cipher_lookup
715 const struct ossl_cipher
*ciph
;
718 static const struct ossl_cipher_lookup ossl_cipher_types
[] = {
719 {"bf-cbc", &ossl_bf_cbc
},
720 {"bf-ecb", &ossl_bf_ecb
},
721 {"bf-cfb", &ossl_bf_cfb
},
722 {"des-ecb", &ossl_des_ecb
},
723 {"des-cbc", &ossl_des_cbc
},
724 {"des3-ecb", &ossl_des3_ecb
},
725 {"des3-cbc", &ossl_des3_cbc
},
726 {"cast5-ecb", &ossl_cast_ecb
},
727 {"cast5-cbc", &ossl_cast_cbc
},
728 {"aes-ecb", &ossl_aes_ecb
},
729 {"aes-cbc", &ossl_aes_cbc
},
733 /* PUBLIC functions */
736 px_find_cipher(const char *name
, PX_Cipher
**res
)
738 const struct ossl_cipher_lookup
*i
;
743 name
= px_resolve_alias(ossl_aliases
, name
);
744 for (i
= ossl_cipher_types
; i
->name
; i
++)
745 if (strcmp(i
->name
, name
) == 0)
748 return PXE_NO_CIPHER
;
750 ResourceOwnerEnlarge(CurrentResourceOwner
);
753 * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
754 * The order is crucial, to make sure we don't leak anything on
755 * out-of-memory or other error.
757 od
= MemoryContextAllocZero(TopMemoryContext
, sizeof(*od
));
760 /* Allocate an EVP_CIPHER_CTX object. */
761 ctx
= EVP_CIPHER_CTX_new();
765 return PXE_CIPHER_INIT
;
769 od
->owner
= CurrentResourceOwner
;
770 ResourceOwnerRememberOSSLCipher(od
->owner
, od
);
772 if (i
->ciph
->cipher_func
)
773 od
->evp_ciph
= i
->ciph
->cipher_func();
775 /* The PX_Cipher is allocated in current memory context */
776 c
= palloc(sizeof(*c
));
777 c
->block_size
= gen_ossl_block_size
;
778 c
->key_size
= gen_ossl_key_size
;
779 c
->iv_size
= gen_ossl_iv_size
;
780 c
->free
= gen_ossl_free
;
781 c
->init
= od
->ciph
->init
;
782 c
->encrypt
= gen_ossl_encrypt
;
783 c
->decrypt
= gen_ossl_decrypt
;
790 /* ResourceOwner callbacks for OSSLCipher */
793 ResOwnerReleaseOSSLCipher(Datum res
)
795 free_openssl_cipher((OSSLCipher
*) DatumGetPointer(res
));