2626 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2727 * SUCH DAMAGE.
2828 *
29- * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.26 2005/10/15 02:49:06 momjian Exp $
29+ * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.27 2006/02/18 20:48:51 neilc Exp $
3030 */
3131
3232#include "postgres.h"
4747#define MAX_IV (128/8)
4848
4949/*
50- * Does OpenSSL support AES?
50+ * Compatibility with OpenSSL 0.9.6
51+ *
52+ * It needs AES and newer DES and digest API.
5153 */
5254#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5355
54- /* Yes, it does. */
56+ /*
57+ * Nothing needed for OpenSSL 0.9.7+
58+ */
59+
5560#include <openssl/aes.h>
61+
5662#else /* old OPENSSL */
5763
5864/*
59- * No, it does not. So use included rijndael code to emulate it .
65+ * Emulate OpenSSL AES .
6066 */
67+
6168#include "rijndael.c"
6269
6370#define AES_ENCRYPT 1
9097 memcpy(iv, (src) + (len) - 16, 16); \
9198 } \
9299 } while (0)
93- #endif /* old OPENSSL */
94100
95101/*
96- * Compatibility with older OpenSSL API for DES.
102+ * Emulate DES_* API
97103 */
98- #if OPENSSL_VERSION_NUMBER < 0x00907000L
104+
99105#define DES_key_schedule des_key_schedule
100106#define DES_cblock des_cblock
101107#define DES_set_key (k , ks ) \
110116#define DES_ede3_cbc_encrypt (i , o , l , k1 , k2 , k3 , iv , e ) \
111117 des_ede3_cbc_encrypt((i), (o), \
112118 (l), *(k1), *(k2), *(k3), (iv), (e))
113- #endif
119+
120+ /*
121+ * Emulate newer digest API.
122+ */
123+
124+ static void EVP_MD_CTX_init (EVP_MD_CTX * ctx )
125+ {
126+ memset (ctx , 0 , sizeof (* ctx ));
127+ }
128+
129+ static int EVP_MD_CTX_cleanup (EVP_MD_CTX * ctx )
130+ {
131+ memset (ctx , 0 , sizeof (* ctx ));
132+ return 1 ;
133+ }
134+
135+ static int EVP_DigestInit_ex (EVP_MD_CTX * ctx , const EVP_MD * md , void * engine )
136+ {
137+ EVP_DigestInit (ctx , md );
138+ return 1 ;
139+ }
140+
141+ static int EVP_DigestFinal_ex (EVP_MD_CTX * ctx , unsigned char * res , unsigned int * len )
142+ {
143+ EVP_DigestFinal (ctx , res , len );
144+ return 1 ;
145+ }
146+
147+ #endif /* old OpenSSL */
114148
115149/*
116150 * Hashes
117151 */
152+
153+ typedef struct OSSLDigest {
154+ const EVP_MD * algo ;
155+ EVP_MD_CTX ctx ;
156+ } OSSLDigest ;
157+
118158static unsigned
119159digest_result_size (PX_MD * h )
120160{
121- return EVP_MD_CTX_size ((EVP_MD_CTX * ) h -> p .ptr );
161+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
162+ return EVP_MD_CTX_size (& digest -> ctx );
122163}
123164
124165static unsigned
125166digest_block_size (PX_MD * h )
126167{
127- return EVP_MD_CTX_block_size ((EVP_MD_CTX * ) h -> p .ptr );
168+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
169+ return EVP_MD_CTX_block_size (& digest -> ctx );
128170}
129171
130172static void
131173digest_reset (PX_MD * h )
132174{
133- EVP_MD_CTX * ctx = (EVP_MD_CTX * ) h -> p .ptr ;
134- const EVP_MD * md ;
175+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
135176
136- md = EVP_MD_CTX_md (ctx );
137-
138- EVP_DigestInit (ctx , md );
177+ EVP_DigestInit_ex (& digest -> ctx , digest -> algo , NULL );
139178}
140179
141180static void
142181digest_update (PX_MD * h , const uint8 * data , unsigned dlen )
143182{
144- EVP_MD_CTX * ctx = (EVP_MD_CTX * ) h -> p .ptr ;
183+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
145184
146- EVP_DigestUpdate (ctx , data , dlen );
185+ EVP_DigestUpdate (& digest -> ctx , data , dlen );
147186}
148187
149188static void
150189digest_finish (PX_MD * h , uint8 * dst )
151190{
152- EVP_MD_CTX * ctx = (EVP_MD_CTX * ) h -> p .ptr ;
153- const EVP_MD * md = EVP_MD_CTX_md (ctx );
154-
155- EVP_DigestFinal (ctx , dst , NULL );
191+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
156192
157- /*
158- * Some builds of 0.9.7x clear all of ctx in EVP_DigestFinal. Fix it by
159- * reinitializing ctx.
160- */
161- EVP_DigestInit (ctx , md );
193+ EVP_DigestFinal_ex (& digest -> ctx , dst , NULL );
162194}
163195
164196static void
165197digest_free (PX_MD * h )
166198{
167- EVP_MD_CTX * ctx = (EVP_MD_CTX * ) h -> p .ptr ;
199+ OSSLDigest * digest = (OSSLDigest * )h -> p .ptr ;
200+
201+ EVP_MD_CTX_cleanup (& digest -> ctx );
168202
169- px_free (ctx );
203+ px_free (digest );
170204 px_free (h );
171205}
172206
178212px_find_digest (const char * name , PX_MD * * res )
179213{
180214 const EVP_MD * md ;
181- EVP_MD_CTX * ctx ;
182215 PX_MD * h ;
216+ OSSLDigest * digest ;
183217
184218 if (!px_openssl_initialized )
185219 {
@@ -191,8 +225,12 @@ px_find_digest(const char *name, PX_MD ** res)
191225 if (md == NULL )
192226 return PXE_NO_HASH ;
193227
194- ctx = px_alloc (sizeof (* ctx ));
195- EVP_DigestInit (ctx , md );
228+ digest = px_alloc (sizeof (* digest ));
229+ digest -> algo = md ;
230+
231+ EVP_MD_CTX_init (& digest -> ctx );
232+ if (EVP_DigestInit_ex (& digest -> ctx , digest -> algo , NULL ) == 0 )
233+ return -1 ;
196234
197235 h = px_alloc (sizeof (* h ));
198236 h -> result_size = digest_result_size ;
@@ -201,7 +239,7 @@ px_find_digest(const char *name, PX_MD ** res)
201239 h -> update = digest_update ;
202240 h -> finish = digest_finish ;
203241 h -> free = digest_free ;
204- h -> p .ptr = (void * ) ctx ;
242+ h -> p .ptr = (void * ) digest ;
205243
206244 * res = h ;
207245 return 0 ;
0 commit comments