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 "px.h"
35 
36 #include <openssl/evp.h>
37 #include <openssl/err.h>
38 #include <openssl/rand.h>
39 
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 on abort, we keep OSSLDigest
55  * objects in a linked list, allocated in TopMemoryContext. We use the
56  * ResourceOwner mechanism to free them on abort.
57  */
58 typedef struct OSSLDigest
59 {
60 	const EVP_MD *algo;
61 	EVP_MD_CTX *ctx;
62 
63 	ResourceOwner owner;
64 	struct OSSLDigest *next;
65 	struct OSSLDigest *prev;
66 } OSSLDigest;
67 
68 static OSSLDigest *open_digests = NULL;
69 static bool digest_resowner_callback_registered = false;
70 
71 static void
free_openssl_digest(OSSLDigest * digest)72 free_openssl_digest(OSSLDigest *digest)
73 {
74 	EVP_MD_CTX_destroy(digest->ctx);
75 	if (digest->prev)
76 		digest->prev->next = digest->next;
77 	else
78 		open_digests = digest->next;
79 	if (digest->next)
80 		digest->next->prev = digest->prev;
81 	pfree(digest);
82 }
83 
84 /*
85  * Close any open OpenSSL handles on abort.
86  */
87 static void
digest_free_callback(ResourceReleasePhase phase,bool isCommit,bool isTopLevel,void * arg)88 digest_free_callback(ResourceReleasePhase phase,
89 					 bool isCommit,
90 					 bool isTopLevel,
91 					 void *arg)
92 {
93 	OSSLDigest *curr;
94 	OSSLDigest *next;
95 
96 	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
97 		return;
98 
99 	next = open_digests;
100 	while (next)
101 	{
102 		curr = next;
103 		next = curr->next;
104 
105 		if (curr->owner == CurrentResourceOwner)
106 		{
107 			if (isCommit)
108 				elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
109 			free_openssl_digest(curr);
110 		}
111 	}
112 }
113 
114 static unsigned
digest_result_size(PX_MD * h)115 digest_result_size(PX_MD *h)
116 {
117 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
118 	int			result = EVP_MD_CTX_size(digest->ctx);
119 
120 	if (result < 0)
121 		elog(ERROR, "EVP_MD_CTX_size() failed");
122 
123 	return result;
124 }
125 
126 static unsigned
digest_block_size(PX_MD * h)127 digest_block_size(PX_MD *h)
128 {
129 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
130 	int			result = EVP_MD_CTX_block_size(digest->ctx);
131 
132 	if (result < 0)
133 		elog(ERROR, "EVP_MD_CTX_block_size() failed");
134 
135 	return result;
136 }
137 
138 static void
digest_reset(PX_MD * h)139 digest_reset(PX_MD *h)
140 {
141 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
142 
143 	if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
144 		elog(ERROR, "EVP_DigestInit_ex() failed");
145 }
146 
147 static void
digest_update(PX_MD * h,const uint8 * data,unsigned dlen)148 digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
149 {
150 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
151 
152 	if (!EVP_DigestUpdate(digest->ctx, data, dlen))
153 		elog(ERROR, "EVP_DigestUpdate() failed");
154 }
155 
156 static void
digest_finish(PX_MD * h,uint8 * dst)157 digest_finish(PX_MD *h, uint8 *dst)
158 {
159 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
160 
161 	if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
162 		elog(ERROR, "EVP_DigestFinal_ex() failed");
163 }
164 
165 static void
digest_free(PX_MD * h)166 digest_free(PX_MD *h)
167 {
168 	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
169 
170 	free_openssl_digest(digest);
171 	px_free(h);
172 }
173 
174 static int	px_openssl_initialized = 0;
175 
176 /* PUBLIC functions */
177 
178 int
px_find_digest(const char * name,PX_MD ** res)179 px_find_digest(const char *name, PX_MD **res)
180 {
181 	const EVP_MD *md;
182 	EVP_MD_CTX *ctx;
183 	PX_MD	   *h;
184 	OSSLDigest *digest;
185 
186 	if (!px_openssl_initialized)
187 	{
188 		px_openssl_initialized = 1;
189 		OpenSSL_add_all_algorithms();
190 	}
191 
192 	if (!digest_resowner_callback_registered)
193 	{
194 		RegisterResourceReleaseCallback(digest_free_callback, NULL);
195 		digest_resowner_callback_registered = true;
196 	}
197 
198 	md = EVP_get_digestbyname(name);
199 	if (md == NULL)
200 		return PXE_NO_HASH;
201 
202 	/*
203 	 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
204 	 * The order is crucial, to make sure we don't leak anything on
205 	 * out-of-memory or other error.
206 	 */
207 	digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
208 
209 	ctx = EVP_MD_CTX_create();
210 	if (!ctx)
211 	{
212 		pfree(digest);
213 		return -1;
214 	}
215 	if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
216 	{
217 		EVP_MD_CTX_destroy(ctx);
218 		pfree(digest);
219 		return -1;
220 	}
221 
222 	digest->algo = md;
223 	digest->ctx = ctx;
224 	digest->owner = CurrentResourceOwner;
225 	digest->next = open_digests;
226 	digest->prev = NULL;
227 	open_digests = digest;
228 
229 	/* The PX_MD object is allocated in the current memory context. */
230 	h = px_alloc(sizeof(*h));
231 	h->result_size = digest_result_size;
232 	h->block_size = digest_block_size;
233 	h->reset = digest_reset;
234 	h->update = digest_update;
235 	h->finish = digest_finish;
236 	h->free = digest_free;
237 	h->p.ptr = (void *) digest;
238 
239 	*res = h;
240 	return 0;
241 }
242 
243 /*
244  * Ciphers
245  *
246  * We use OpenSSL's EVP* family of functions for these.
247  */
248 
249 /*
250  * prototype for the EVP functions that return an algorithm, e.g.
251  * EVP_aes_128_cbc().
252  */
253 typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);
254 
255 /*
256  * ossl_cipher contains the static information about each cipher.
257  */
258 struct ossl_cipher
259 {
260 	int			(*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
261 	ossl_EVP_cipher_func cipher_func;
262 	int			block_size;
263 	int			max_key_size;
264 };
265 
266 /*
267  * OSSLCipher contains the state for using a cipher. A separate OSSLCipher
268  * object is allocated in each px_find_cipher() call.
269  *
270  * To make sure we don't leak OpenSSL handles on abort, we keep OSSLCipher
271  * objects in a linked list, allocated in TopMemoryContext. We use the
272  * ResourceOwner mechanism to free them on abort.
273  */
274 typedef struct OSSLCipher
275 {
276 	EVP_CIPHER_CTX *evp_ctx;
277 	const EVP_CIPHER *evp_ciph;
278 	uint8		key[MAX_KEY];
279 	uint8		iv[MAX_IV];
280 	unsigned	klen;
281 	unsigned	init;
282 	const struct ossl_cipher *ciph;
283 
284 	ResourceOwner owner;
285 	struct OSSLCipher *next;
286 	struct OSSLCipher *prev;
287 } OSSLCipher;
288 
289 static OSSLCipher *open_ciphers = NULL;
290 static bool cipher_resowner_callback_registered = false;
291 
292 static void
free_openssl_cipher(OSSLCipher * od)293 free_openssl_cipher(OSSLCipher *od)
294 {
295 	EVP_CIPHER_CTX_free(od->evp_ctx);
296 	if (od->prev)
297 		od->prev->next = od->next;
298 	else
299 		open_ciphers = od->next;
300 	if (od->next)
301 		od->next->prev = od->prev;
302 	pfree(od);
303 }
304 
305 /*
306  * Close any open OpenSSL cipher handles on abort.
307  */
308 static void
cipher_free_callback(ResourceReleasePhase phase,bool isCommit,bool isTopLevel,void * arg)309 cipher_free_callback(ResourceReleasePhase phase,
310 					 bool isCommit,
311 					 bool isTopLevel,
312 					 void *arg)
313 {
314 	OSSLCipher *curr;
315 	OSSLCipher *next;
316 
317 	if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
318 		return;
319 
320 	next = open_ciphers;
321 	while (next)
322 	{
323 		curr = next;
324 		next = curr->next;
325 
326 		if (curr->owner == CurrentResourceOwner)
327 		{
328 			if (isCommit)
329 				elog(WARNING, "pgcrypto cipher reference leak: cipher %p still referenced", curr);
330 			free_openssl_cipher(curr);
331 		}
332 	}
333 }
334 
335 /* Common routines for all algorithms */
336 
337 static unsigned
gen_ossl_block_size(PX_Cipher * c)338 gen_ossl_block_size(PX_Cipher *c)
339 {
340 	OSSLCipher *od = (OSSLCipher *) c->ptr;
341 
342 	return od->ciph->block_size;
343 }
344 
345 static unsigned
gen_ossl_key_size(PX_Cipher * c)346 gen_ossl_key_size(PX_Cipher *c)
347 {
348 	OSSLCipher *od = (OSSLCipher *) c->ptr;
349 
350 	return od->ciph->max_key_size;
351 }
352 
353 static unsigned
gen_ossl_iv_size(PX_Cipher * c)354 gen_ossl_iv_size(PX_Cipher *c)
355 {
356 	unsigned	ivlen;
357 	OSSLCipher *od = (OSSLCipher *) c->ptr;
358 
359 	ivlen = od->ciph->block_size;
360 	return ivlen;
361 }
362 
363 static void
gen_ossl_free(PX_Cipher * c)364 gen_ossl_free(PX_Cipher *c)
365 {
366 	OSSLCipher *od = (OSSLCipher *) c->ptr;
367 
368 	free_openssl_cipher(od);
369 	px_free(c);
370 }
371 
372 static int
gen_ossl_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)373 gen_ossl_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
374 				 uint8 *res)
375 {
376 	OSSLCipher *od = c->ptr;
377 	int			outlen;
378 
379 	if (!od->init)
380 	{
381 		if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
382 			return PXE_CIPHER_INIT;
383 		if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
384 			return PXE_CIPHER_INIT;
385 		if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
386 			return PXE_CIPHER_INIT;
387 		if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
388 			return PXE_CIPHER_INIT;
389 		od->init = true;
390 	}
391 
392 	if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
393 		return PXE_DECRYPT_FAILED;
394 
395 	return 0;
396 }
397 
398 static int
gen_ossl_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)399 gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
400 				 uint8 *res)
401 {
402 	OSSLCipher *od = c->ptr;
403 	int			outlen;
404 
405 	if (!od->init)
406 	{
407 		if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))
408 			return PXE_CIPHER_INIT;
409 		if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, 0))
410 			return PXE_CIPHER_INIT;
411 		if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))
412 			return PXE_CIPHER_INIT;
413 		if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))
414 			return PXE_CIPHER_INIT;
415 		od->init = true;
416 	}
417 
418 	if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))
419 		return PXE_ERR_GENERIC;
420 
421 	return 0;
422 }
423 
424 /* Blowfish */
425 
426 /*
427  * Check if strong crypto is supported. Some OpenSSL installations
428  * support only short keys and unfortunately BF_set_key does not return any
429  * error value. This function tests if is possible to use strong key.
430  */
431 static int
bf_check_supported_key_len(void)432 bf_check_supported_key_len(void)
433 {
434 	static const uint8 key[56] = {
435 		0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
436 		0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
437 		0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
438 		0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
439 		0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
440 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
441 	};
442 
443 	static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
444 	static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
445 	uint8		out[8];
446 	EVP_CIPHER_CTX *evp_ctx;
447 	int			outlen;
448 	int			status = 0;
449 
450 	/* encrypt with 448bits key and verify output */
451 	evp_ctx = EVP_CIPHER_CTX_new();
452 	if (!evp_ctx)
453 		return 0;
454 	if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))
455 		goto leave;
456 	if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))
457 		goto leave;
458 	if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL))
459 		goto leave;
460 
461 	if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8))
462 		goto leave;
463 
464 	if (memcmp(out, res, 8) != 0)
465 		goto leave;				/* Output does not match -> strong cipher is
466 								 * not supported */
467 	status = 1;
468 
469 leave:
470 	EVP_CIPHER_CTX_free(evp_ctx);
471 	return status;
472 }
473 
474 static int
bf_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)475 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
476 {
477 	OSSLCipher *od = c->ptr;
478 	unsigned	bs = gen_ossl_block_size(c);
479 	static int	bf_is_strong = -1;
480 
481 	/*
482 	 * Test if key len is supported. BF_set_key silently cut large keys and it
483 	 * could be a problem when user transfer crypted data from one server to
484 	 * another.
485 	 */
486 
487 	if (bf_is_strong == -1)
488 		bf_is_strong = bf_check_supported_key_len();
489 
490 	if (!bf_is_strong && klen > 16)
491 		return PXE_KEY_TOO_BIG;
492 
493 	/* Key len is supported. We can use it. */
494 	od->klen = klen;
495 	memcpy(od->key, key, klen);
496 
497 	if (iv)
498 		memcpy(od->iv, iv, bs);
499 	else
500 		memset(od->iv, 0, bs);
501 	return 0;
502 }
503 
504 /* DES */
505 
506 static int
ossl_des_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)507 ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
508 {
509 	OSSLCipher *od = c->ptr;
510 	unsigned	bs = gen_ossl_block_size(c);
511 
512 	od->klen = 8;
513 	memset(od->key, 0, 8);
514 	memcpy(od->key, key, klen > 8 ? 8 : klen);
515 
516 	if (iv)
517 		memcpy(od->iv, iv, bs);
518 	else
519 		memset(od->iv, 0, bs);
520 	return 0;
521 }
522 
523 /* DES3 */
524 
525 static int
ossl_des3_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)526 ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
527 {
528 	OSSLCipher *od = c->ptr;
529 	unsigned	bs = gen_ossl_block_size(c);
530 
531 	od->klen = 24;
532 	memset(od->key, 0, 24);
533 	memcpy(od->key, key, klen > 24 ? 24 : klen);
534 
535 	if (iv)
536 		memcpy(od->iv, iv, bs);
537 	else
538 		memset(od->iv, 0, bs);
539 	return 0;
540 }
541 
542 /* CAST5 */
543 
544 static int
ossl_cast_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)545 ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
546 {
547 	OSSLCipher *od = c->ptr;
548 	unsigned	bs = gen_ossl_block_size(c);
549 
550 	od->klen = klen;
551 	memcpy(od->key, key, klen);
552 
553 	if (iv)
554 		memcpy(od->iv, iv, bs);
555 	else
556 		memset(od->iv, 0, bs);
557 	return 0;
558 }
559 
560 /* AES */
561 
562 static int
ossl_aes_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)563 ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
564 {
565 	OSSLCipher *od = c->ptr;
566 	unsigned	bs = gen_ossl_block_size(c);
567 
568 	if (klen <= 128 / 8)
569 		od->klen = 128 / 8;
570 	else if (klen <= 192 / 8)
571 		od->klen = 192 / 8;
572 	else if (klen <= 256 / 8)
573 		od->klen = 256 / 8;
574 	else
575 		return PXE_KEY_TOO_BIG;
576 
577 	memcpy(od->key, key, klen);
578 
579 	if (iv)
580 		memcpy(od->iv, iv, bs);
581 	else
582 		memset(od->iv, 0, bs);
583 
584 	return 0;
585 }
586 
587 static int
ossl_aes_ecb_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)588 ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
589 {
590 	OSSLCipher *od = c->ptr;
591 	int			err;
592 
593 	err = ossl_aes_init(c, key, klen, iv);
594 	if (err)
595 		return err;
596 
597 	switch (od->klen)
598 	{
599 		case 128 / 8:
600 			od->evp_ciph = EVP_aes_128_ecb();
601 			break;
602 		case 192 / 8:
603 			od->evp_ciph = EVP_aes_192_ecb();
604 			break;
605 		case 256 / 8:
606 			od->evp_ciph = EVP_aes_256_ecb();
607 			break;
608 		default:
609 			/* shouldn't happen */
610 			err = PXE_CIPHER_INIT;
611 			break;
612 	}
613 
614 	return err;
615 }
616 
617 static int
ossl_aes_cbc_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)618 ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
619 {
620 	OSSLCipher *od = c->ptr;
621 	int			err;
622 
623 	err = ossl_aes_init(c, key, klen, iv);
624 	if (err)
625 		return err;
626 
627 	switch (od->klen)
628 	{
629 		case 128 / 8:
630 			od->evp_ciph = EVP_aes_128_cbc();
631 			break;
632 		case 192 / 8:
633 			od->evp_ciph = EVP_aes_192_cbc();
634 			break;
635 		case 256 / 8:
636 			od->evp_ciph = EVP_aes_256_cbc();
637 			break;
638 		default:
639 			/* shouldn't happen */
640 			err = PXE_CIPHER_INIT;
641 			break;
642 	}
643 
644 	return err;
645 }
646 
647 /*
648  * aliases
649  */
650 
651 static PX_Alias ossl_aliases[] = {
652 	{"bf", "bf-cbc"},
653 	{"blowfish", "bf-cbc"},
654 	{"blowfish-cbc", "bf-cbc"},
655 	{"blowfish-ecb", "bf-ecb"},
656 	{"blowfish-cfb", "bf-cfb"},
657 	{"des", "des-cbc"},
658 	{"3des", "des3-cbc"},
659 	{"3des-ecb", "des3-ecb"},
660 	{"3des-cbc", "des3-cbc"},
661 	{"cast5", "cast5-cbc"},
662 	{"aes", "aes-cbc"},
663 	{"rijndael", "aes-cbc"},
664 	{"rijndael-cbc", "aes-cbc"},
665 	{"rijndael-ecb", "aes-ecb"},
666 	{NULL}
667 };
668 
669 static const struct ossl_cipher ossl_bf_cbc = {
670 	bf_init,
671 	EVP_bf_cbc,
672 	64 / 8, 448 / 8
673 };
674 
675 static const struct ossl_cipher ossl_bf_ecb = {
676 	bf_init,
677 	EVP_bf_ecb,
678 	64 / 8, 448 / 8
679 };
680 
681 static const struct ossl_cipher ossl_bf_cfb = {
682 	bf_init,
683 	EVP_bf_cfb,
684 	64 / 8, 448 / 8
685 };
686 
687 static const struct ossl_cipher ossl_des_ecb = {
688 	ossl_des_init,
689 	EVP_des_ecb,
690 	64 / 8, 64 / 8
691 };
692 
693 static const struct ossl_cipher ossl_des_cbc = {
694 	ossl_des_init,
695 	EVP_des_cbc,
696 	64 / 8, 64 / 8
697 };
698 
699 static const struct ossl_cipher ossl_des3_ecb = {
700 	ossl_des3_init,
701 	EVP_des_ede3_ecb,
702 	64 / 8, 192 / 8
703 };
704 
705 static const struct ossl_cipher ossl_des3_cbc = {
706 	ossl_des3_init,
707 	EVP_des_ede3_cbc,
708 	64 / 8, 192 / 8
709 };
710 
711 static const struct ossl_cipher ossl_cast_ecb = {
712 	ossl_cast_init,
713 	EVP_cast5_ecb,
714 	64 / 8, 128 / 8
715 };
716 
717 static const struct ossl_cipher ossl_cast_cbc = {
718 	ossl_cast_init,
719 	EVP_cast5_cbc,
720 	64 / 8, 128 / 8
721 };
722 
723 static const struct ossl_cipher ossl_aes_ecb = {
724 	ossl_aes_ecb_init,
725 	NULL,						/* EVP_aes_XXX_ecb(), determined in init
726 								 * function */
727 	128 / 8, 256 / 8
728 };
729 
730 static const struct ossl_cipher ossl_aes_cbc = {
731 	ossl_aes_cbc_init,
732 	NULL,						/* EVP_aes_XXX_cbc(), determined in init
733 								 * function */
734 	128 / 8, 256 / 8
735 };
736 
737 /*
738  * Special handlers
739  */
740 struct ossl_cipher_lookup
741 {
742 	const char *name;
743 	const struct ossl_cipher *ciph;
744 };
745 
746 static const struct ossl_cipher_lookup ossl_cipher_types[] = {
747 	{"bf-cbc", &ossl_bf_cbc},
748 	{"bf-ecb", &ossl_bf_ecb},
749 	{"bf-cfb", &ossl_bf_cfb},
750 	{"des-ecb", &ossl_des_ecb},
751 	{"des-cbc", &ossl_des_cbc},
752 	{"des3-ecb", &ossl_des3_ecb},
753 	{"des3-cbc", &ossl_des3_cbc},
754 	{"cast5-ecb", &ossl_cast_ecb},
755 	{"cast5-cbc", &ossl_cast_cbc},
756 	{"aes-ecb", &ossl_aes_ecb},
757 	{"aes-cbc", &ossl_aes_cbc},
758 	{NULL}
759 };
760 
761 /* PUBLIC functions */
762 
763 int
px_find_cipher(const char * name,PX_Cipher ** res)764 px_find_cipher(const char *name, PX_Cipher **res)
765 {
766 	const struct ossl_cipher_lookup *i;
767 	PX_Cipher  *c = NULL;
768 	EVP_CIPHER_CTX *ctx;
769 	OSSLCipher *od;
770 
771 	name = px_resolve_alias(ossl_aliases, name);
772 	for (i = ossl_cipher_types; i->name; i++)
773 		if (strcmp(i->name, name) == 0)
774 			break;
775 	if (i->name == NULL)
776 		return PXE_NO_CIPHER;
777 
778 	if (!cipher_resowner_callback_registered)
779 	{
780 		RegisterResourceReleaseCallback(cipher_free_callback, NULL);
781 		cipher_resowner_callback_registered = true;
782 	}
783 
784 	/*
785 	 * Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
786 	 * The order is crucial, to make sure we don't leak anything on
787 	 * out-of-memory or other error.
788 	 */
789 	od = MemoryContextAllocZero(TopMemoryContext, sizeof(*od));
790 	od->ciph = i->ciph;
791 
792 	/* Allocate an EVP_CIPHER_CTX object. */
793 	ctx = EVP_CIPHER_CTX_new();
794 	if (!ctx)
795 	{
796 		pfree(od);
797 		return PXE_CIPHER_INIT;
798 	}
799 
800 	od->evp_ctx = ctx;
801 	od->owner = CurrentResourceOwner;
802 	od->next = open_ciphers;
803 	od->prev = NULL;
804 	open_ciphers = od;
805 
806 	if (i->ciph->cipher_func)
807 		od->evp_ciph = i->ciph->cipher_func();
808 
809 	/* The PX_Cipher is allocated in current memory context */
810 	c = px_alloc(sizeof(*c));
811 	c->block_size = gen_ossl_block_size;
812 	c->key_size = gen_ossl_key_size;
813 	c->iv_size = gen_ossl_iv_size;
814 	c->free = gen_ossl_free;
815 	c->init = od->ciph->init;
816 	c->encrypt = gen_ossl_encrypt;
817 	c->decrypt = gen_ossl_decrypt;
818 	c->ptr = od;
819 
820 	*res = c;
821 	return 0;
822 }
823