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