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/blowfish.h>
38 #include <openssl/cast.h>
39 #include <openssl/des.h>
40 #include <openssl/rand.h>
41 #include <openssl/err.h>
42
43 #include "utils/memutils.h"
44 #include "utils/resowner.h"
45
46 /*
47 * Max lengths we might want to handle.
48 */
49 #define MAX_KEY (512/8)
50 #define MAX_IV (128/8)
51
52 /*
53 * Compatibility with OpenSSL 0.9.6
54 *
55 * It needs AES and newer DES and digest API.
56 */
57 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
58
59 /*
60 * Nothing needed for OpenSSL 0.9.7+
61 */
62
63 #include <openssl/aes.h>
64 #else /* old OPENSSL */
65
66 /*
67 * Emulate OpenSSL AES.
68 */
69
70 #include "rijndael.c"
71
72 #define AES_ENCRYPT 1
73 #define AES_DECRYPT 0
74 #define AES_KEY rijndael_ctx
75
76 static int
AES_set_encrypt_key(const uint8 * key,int kbits,AES_KEY * ctx)77 AES_set_encrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
78 {
79 aes_set_key(ctx, key, kbits, 1);
80 return 0;
81 }
82
83 static int
AES_set_decrypt_key(const uint8 * key,int kbits,AES_KEY * ctx)84 AES_set_decrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
85 {
86 aes_set_key(ctx, key, kbits, 0);
87 return 0;
88 }
89
90 static void
AES_ecb_encrypt(const uint8 * src,uint8 * dst,AES_KEY * ctx,int enc)91 AES_ecb_encrypt(const uint8 *src, uint8 *dst, AES_KEY *ctx, int enc)
92 {
93 memcpy(dst, src, 16);
94 if (enc)
95 aes_ecb_encrypt(ctx, dst, 16);
96 else
97 aes_ecb_decrypt(ctx, dst, 16);
98 }
99
100 static void
AES_cbc_encrypt(const uint8 * src,uint8 * dst,int len,AES_KEY * ctx,uint8 * iv,int enc)101 AES_cbc_encrypt(const uint8 *src, uint8 *dst, int len, AES_KEY *ctx, uint8 *iv, int enc)
102 {
103 memcpy(dst, src, len);
104 if (enc)
105 {
106 aes_cbc_encrypt(ctx, iv, dst, len);
107 memcpy(iv, dst + len - 16, 16);
108 }
109 else
110 {
111 aes_cbc_decrypt(ctx, iv, dst, len);
112 memcpy(iv, src + len - 16, 16);
113 }
114 }
115
116 /*
117 * Emulate DES_* API
118 */
119
120 #define DES_key_schedule des_key_schedule
121 #define DES_cblock des_cblock
122 #define DES_set_key(k, ks) \
123 des_set_key((k), *(ks))
124 #define DES_ecb_encrypt(i, o, k, e) \
125 des_ecb_encrypt((i), (o), *(k), (e))
126 #define DES_ncbc_encrypt(i, o, l, k, iv, e) \
127 des_ncbc_encrypt((i), (o), (l), *(k), (iv), (e))
128 #define DES_ecb3_encrypt(i, o, k1, k2, k3, e) \
129 des_ecb3_encrypt((des_cblock *)(i), (des_cblock *)(o), \
130 *(k1), *(k2), *(k3), (e))
131 #define DES_ede3_cbc_encrypt(i, o, l, k1, k2, k3, iv, e) \
132 des_ede3_cbc_encrypt((i), (o), \
133 (l), *(k1), *(k2), *(k3), (iv), (e))
134
135 /*
136 * Emulate newer digest API.
137 */
138
139 static void
EVP_MD_CTX_init(EVP_MD_CTX * ctx)140 EVP_MD_CTX_init(EVP_MD_CTX *ctx)
141 {
142 memset(ctx, 0, sizeof(*ctx));
143 }
144
145 static int
EVP_MD_CTX_cleanup(EVP_MD_CTX * ctx)146 EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
147 {
148 px_memset(ctx, 0, sizeof(*ctx));
149 return 1;
150 }
151
152 static int
EVP_DigestInit_ex(EVP_MD_CTX * ctx,const EVP_MD * md,void * engine)153 EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
154 {
155 EVP_DigestInit(ctx, md);
156 return 1;
157 }
158
159 static int
EVP_DigestFinal_ex(EVP_MD_CTX * ctx,unsigned char * res,unsigned int * len)160 EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
161 {
162 EVP_DigestFinal(ctx, res, len);
163 return 1;
164 }
165 #endif /* old OpenSSL */
166
167 /*
168 * Provide SHA2 for older OpenSSL < 0.9.8
169 */
170 #if OPENSSL_VERSION_NUMBER < 0x00908000L
171
172 #include "sha2.c"
173 #include "internal-sha2.c"
174
175 typedef void (*init_f) (PX_MD *md);
176
177 static int
compat_find_digest(const char * name,PX_MD ** res)178 compat_find_digest(const char *name, PX_MD **res)
179 {
180 init_f init = NULL;
181
182 if (pg_strcasecmp(name, "sha224") == 0)
183 init = init_sha224;
184 else if (pg_strcasecmp(name, "sha256") == 0)
185 init = init_sha256;
186 else if (pg_strcasecmp(name, "sha384") == 0)
187 init = init_sha384;
188 else if (pg_strcasecmp(name, "sha512") == 0)
189 init = init_sha512;
190 else
191 return PXE_NO_HASH;
192
193 *res = px_alloc(sizeof(PX_MD));
194 init(*res);
195 return 0;
196 }
197 #else
198 #define compat_find_digest(name, res) (PXE_NO_HASH)
199 #endif
200
201 /*
202 * Hashes
203 */
204
205 /*
206 * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
207 * objects in a linked list, allocated in TopMemoryContext. We use the
208 * ResourceOwner mechanism to free them on abort.
209 */
210 typedef struct OSSLDigest
211 {
212 const EVP_MD *algo;
213 EVP_MD_CTX *ctx;
214
215 ResourceOwner owner;
216 struct OSSLDigest *next;
217 struct OSSLDigest *prev;
218 } OSSLDigest;
219
220 static OSSLDigest *open_digests = NULL;
221 static bool resowner_callback_registered = false;
222
223 static void
free_openssldigest(OSSLDigest * digest)224 free_openssldigest(OSSLDigest *digest)
225 {
226 EVP_MD_CTX_destroy(digest->ctx);
227 if (digest->prev)
228 digest->prev->next = digest->next;
229 else
230 open_digests = digest->next;
231 if (digest->next)
232 digest->next->prev = digest->prev;
233 pfree(digest);
234 }
235
236 /*
237 * Close any open OpenSSL handles on abort.
238 */
239 static void
digest_free_callback(ResourceReleasePhase phase,bool isCommit,bool isTopLevel,void * arg)240 digest_free_callback(ResourceReleasePhase phase,
241 bool isCommit,
242 bool isTopLevel,
243 void *arg)
244 {
245 OSSLDigest *curr;
246 OSSLDigest *next;
247
248 if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
249 return;
250
251 next = open_digests;
252 while (next)
253 {
254 curr = next;
255 next = curr->next;
256
257 if (curr->owner == CurrentResourceOwner)
258 {
259 if (isCommit)
260 elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
261 free_openssldigest(curr);
262 }
263 }
264 }
265
266 static unsigned
digest_result_size(PX_MD * h)267 digest_result_size(PX_MD *h)
268 {
269 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
270 int result = EVP_MD_CTX_size(digest->ctx);
271
272 if (result < 0)
273 elog(ERROR, "EVP_MD_CTX_size() failed");
274
275 return result;
276 }
277
278 static unsigned
digest_block_size(PX_MD * h)279 digest_block_size(PX_MD *h)
280 {
281 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
282 int result = EVP_MD_CTX_block_size(digest->ctx);
283
284 if (result < 0)
285 elog(ERROR, "EVP_MD_CTX_block_size() failed");
286
287 return result;
288 }
289
290 static void
digest_reset(PX_MD * h)291 digest_reset(PX_MD *h)
292 {
293 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
294
295 if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))
296 elog(ERROR, "EVP_DigestInit_ex() failed");
297 }
298
299 static void
digest_update(PX_MD * h,const uint8 * data,unsigned dlen)300 digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
301 {
302 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
303
304 if (!EVP_DigestUpdate(digest->ctx, data, dlen))
305 elog(ERROR, "EVP_DigestUpdate() failed");
306 }
307
308 static void
digest_finish(PX_MD * h,uint8 * dst)309 digest_finish(PX_MD *h, uint8 *dst)
310 {
311 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
312
313 if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))
314 elog(ERROR, "EVP_DigestFinal_ex() failed");
315 }
316
317 static void
digest_free(PX_MD * h)318 digest_free(PX_MD *h)
319 {
320 OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
321
322 free_openssldigest(digest);
323 px_free(h);
324 }
325
326 static int px_openssl_initialized = 0;
327
328 /* PUBLIC functions */
329
330 int
px_find_digest(const char * name,PX_MD ** res)331 px_find_digest(const char *name, PX_MD **res)
332 {
333 const EVP_MD *md;
334 EVP_MD_CTX *ctx;
335 PX_MD *h;
336 OSSLDigest *digest;
337
338 if (!px_openssl_initialized)
339 {
340 px_openssl_initialized = 1;
341 OpenSSL_add_all_algorithms();
342 }
343
344 if (!resowner_callback_registered)
345 {
346 RegisterResourceReleaseCallback(digest_free_callback, NULL);
347 resowner_callback_registered = true;
348 }
349
350 md = EVP_get_digestbyname(name);
351 if (md == NULL)
352 return compat_find_digest(name, res);
353
354 /*
355 * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
356 * The order is crucial, to make sure we don't leak anything on
357 * out-of-memory or other error.
358 */
359 digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
360
361 ctx = EVP_MD_CTX_create();
362 if (!ctx)
363 {
364 pfree(digest);
365 return -1;
366 }
367 if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
368 {
369 EVP_MD_CTX_destroy(ctx);
370 pfree(digest);
371 return -1;
372 }
373
374 digest->algo = md;
375 digest->ctx = ctx;
376 digest->owner = CurrentResourceOwner;
377 digest->next = open_digests;
378 digest->prev = NULL;
379 open_digests = digest;
380
381 /* The PX_MD object is allocated in the current memory context. */
382 h = px_alloc(sizeof(*h));
383 h->result_size = digest_result_size;
384 h->block_size = digest_block_size;
385 h->reset = digest_reset;
386 h->update = digest_update;
387 h->finish = digest_finish;
388 h->free = digest_free;
389 h->p.ptr = (void *) digest;
390
391 *res = h;
392 return 0;
393 }
394
395 /*
396 * Ciphers
397 *
398 * The problem with OpenSSL is that the EVP* family
399 * of functions does not allow enough flexibility
400 * and forces some of the parameters (keylen,
401 * padding) to SSL defaults.
402 *
403 * So need to manage ciphers ourselves.
404 */
405
406 struct ossl_cipher
407 {
408 int (*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
409 int (*encrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
410 int (*decrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
411
412 int block_size;
413 int max_key_size;
414 int stream_cipher;
415 };
416
417 typedef struct
418 {
419 union
420 {
421 struct
422 {
423 BF_KEY key;
424 int num;
425 } bf;
426 struct
427 {
428 DES_key_schedule key_schedule;
429 } des;
430 struct
431 {
432 DES_key_schedule k1,
433 k2,
434 k3;
435 } des3;
436 CAST_KEY cast_key;
437 AES_KEY aes_key;
438 } u;
439 uint8 key[MAX_KEY];
440 uint8 iv[MAX_IV];
441 unsigned klen;
442 unsigned init;
443 const struct ossl_cipher *ciph;
444 } ossldata;
445
446 /* generic */
447
448 static unsigned
gen_ossl_block_size(PX_Cipher * c)449 gen_ossl_block_size(PX_Cipher *c)
450 {
451 ossldata *od = (ossldata *) c->ptr;
452
453 return od->ciph->block_size;
454 }
455
456 static unsigned
gen_ossl_key_size(PX_Cipher * c)457 gen_ossl_key_size(PX_Cipher *c)
458 {
459 ossldata *od = (ossldata *) c->ptr;
460
461 return od->ciph->max_key_size;
462 }
463
464 static unsigned
gen_ossl_iv_size(PX_Cipher * c)465 gen_ossl_iv_size(PX_Cipher *c)
466 {
467 unsigned ivlen;
468 ossldata *od = (ossldata *) c->ptr;
469
470 ivlen = od->ciph->block_size;
471 return ivlen;
472 }
473
474 static void
gen_ossl_free(PX_Cipher * c)475 gen_ossl_free(PX_Cipher *c)
476 {
477 ossldata *od = (ossldata *) c->ptr;
478
479 px_memset(od, 0, sizeof(*od));
480 px_free(od);
481 px_free(c);
482 }
483
484 /* Blowfish */
485
486 /*
487 * Check if strong crypto is supported. Some openssl installations
488 * support only short keys and unfortunately BF_set_key does not return any
489 * error value. This function tests if is possible to use strong key.
490 */
491 static int
bf_check_supported_key_len(void)492 bf_check_supported_key_len(void)
493 {
494 static const uint8 key[56] = {
495 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
496 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
497 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
498 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
499 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
500 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
501 };
502
503 static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
504 static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
505 static uint8 out[8];
506
507 BF_KEY bf_key;
508
509 /* encrypt with 448bits key and verify output */
510 BF_set_key(&bf_key, 56, key);
511 BF_ecb_encrypt(data, out, &bf_key, BF_ENCRYPT);
512
513 if (memcmp(out, res, 8) != 0)
514 return 0; /* Output does not match -> strong cipher is
515 * not supported */
516 return 1;
517 }
518
519 static int
bf_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)520 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
521 {
522 ossldata *od = c->ptr;
523 static int bf_is_strong = -1;
524
525 /*
526 * Test if key len is supported. BF_set_key silently cut large keys and it
527 * could be a problem when user transfer crypted data from one server to
528 * another.
529 */
530
531 if (bf_is_strong == -1)
532 bf_is_strong = bf_check_supported_key_len();
533
534 if (!bf_is_strong && klen > 16)
535 return PXE_KEY_TOO_BIG;
536
537 /* Key len is supported. We can use it. */
538 BF_set_key(&od->u.bf.key, klen, key);
539 if (iv)
540 memcpy(od->iv, iv, BF_BLOCK);
541 else
542 memset(od->iv, 0, BF_BLOCK);
543 od->u.bf.num = 0;
544 return 0;
545 }
546
547 static int
bf_ecb_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)548 bf_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
549 {
550 unsigned bs = gen_ossl_block_size(c);
551 unsigned i;
552 ossldata *od = c->ptr;
553
554 for (i = 0; i < dlen / bs; i++)
555 BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT);
556 return 0;
557 }
558
559 static int
bf_ecb_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)560 bf_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
561 {
562 unsigned bs = gen_ossl_block_size(c),
563 i;
564 ossldata *od = c->ptr;
565
566 for (i = 0; i < dlen / bs; i++)
567 BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT);
568 return 0;
569 }
570
571 static int
bf_cbc_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)572 bf_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
573 {
574 ossldata *od = c->ptr;
575
576 BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT);
577 return 0;
578 }
579
580 static int
bf_cbc_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)581 bf_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
582 {
583 ossldata *od = c->ptr;
584
585 BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT);
586 return 0;
587 }
588
589 static int
bf_cfb64_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)590 bf_cfb64_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
591 {
592 ossldata *od = c->ptr;
593
594 BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
595 &od->u.bf.num, BF_ENCRYPT);
596 return 0;
597 }
598
599 static int
bf_cfb64_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)600 bf_cfb64_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
601 {
602 ossldata *od = c->ptr;
603
604 BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
605 &od->u.bf.num, BF_DECRYPT);
606 return 0;
607 }
608
609 /* DES */
610
611 static int
ossl_des_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)612 ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
613 {
614 ossldata *od = c->ptr;
615 DES_cblock xkey;
616
617 memset(&xkey, 0, sizeof(xkey));
618 memcpy(&xkey, key, klen > 8 ? 8 : klen);
619 DES_set_key(&xkey, &od->u.des.key_schedule);
620 memset(&xkey, 0, sizeof(xkey));
621
622 if (iv)
623 memcpy(od->iv, iv, 8);
624 else
625 memset(od->iv, 0, 8);
626 return 0;
627 }
628
629 static int
ossl_des_ecb_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)630 ossl_des_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
631 uint8 *res)
632 {
633 unsigned bs = gen_ossl_block_size(c);
634 unsigned i;
635 ossldata *od = c->ptr;
636
637 for (i = 0; i < dlen / bs; i++)
638 DES_ecb_encrypt((DES_cblock *) (data + i * bs),
639 (DES_cblock *) (res + i * bs),
640 &od->u.des.key_schedule, 1);
641 return 0;
642 }
643
644 static int
ossl_des_ecb_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)645 ossl_des_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
646 uint8 *res)
647 {
648 unsigned bs = gen_ossl_block_size(c);
649 unsigned i;
650 ossldata *od = c->ptr;
651
652 for (i = 0; i < dlen / bs; i++)
653 DES_ecb_encrypt((DES_cblock *) (data + i * bs),
654 (DES_cblock *) (res + i * bs),
655 &od->u.des.key_schedule, 0);
656 return 0;
657 }
658
659 static int
ossl_des_cbc_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)660 ossl_des_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
661 uint8 *res)
662 {
663 ossldata *od = c->ptr;
664
665 DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule,
666 (DES_cblock *) od->iv, 1);
667 return 0;
668 }
669
670 static int
ossl_des_cbc_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)671 ossl_des_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
672 uint8 *res)
673 {
674 ossldata *od = c->ptr;
675
676 DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule,
677 (DES_cblock *) od->iv, 0);
678 return 0;
679 }
680
681 /* DES3 */
682
683 static int
ossl_des3_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)684 ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
685 {
686 ossldata *od = c->ptr;
687 DES_cblock xkey1,
688 xkey2,
689 xkey3;
690
691 memset(&xkey1, 0, sizeof(xkey1));
692 memset(&xkey2, 0, sizeof(xkey2));
693 memset(&xkey3, 0, sizeof(xkey3));
694 memcpy(&xkey1, key, klen > 8 ? 8 : klen);
695 if (klen > 8)
696 memcpy(&xkey2, key + 8, (klen - 8) > 8 ? 8 : (klen - 8));
697 if (klen > 16)
698 memcpy(&xkey3, key + 16, (klen - 16) > 8 ? 8 : (klen - 16));
699
700 DES_set_key(&xkey1, &od->u.des3.k1);
701 DES_set_key(&xkey2, &od->u.des3.k2);
702 DES_set_key(&xkey3, &od->u.des3.k3);
703 memset(&xkey1, 0, sizeof(xkey1));
704 memset(&xkey2, 0, sizeof(xkey2));
705 memset(&xkey3, 0, sizeof(xkey3));
706
707 if (iv)
708 memcpy(od->iv, iv, 8);
709 else
710 memset(od->iv, 0, 8);
711 return 0;
712 }
713
714 static int
ossl_des3_ecb_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)715 ossl_des3_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
716 uint8 *res)
717 {
718 unsigned bs = gen_ossl_block_size(c);
719 unsigned i;
720 ossldata *od = c->ptr;
721
722 for (i = 0; i < dlen / bs; i++)
723 DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
724 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 1);
725 return 0;
726 }
727
728 static int
ossl_des3_ecb_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)729 ossl_des3_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
730 uint8 *res)
731 {
732 unsigned bs = gen_ossl_block_size(c);
733 unsigned i;
734 ossldata *od = c->ptr;
735
736 for (i = 0; i < dlen / bs; i++)
737 DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
738 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 0);
739 return 0;
740 }
741
742 static int
ossl_des3_cbc_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)743 ossl_des3_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
744 uint8 *res)
745 {
746 ossldata *od = c->ptr;
747
748 DES_ede3_cbc_encrypt(data, res, dlen,
749 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
750 (DES_cblock *) od->iv, 1);
751 return 0;
752 }
753
754 static int
ossl_des3_cbc_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)755 ossl_des3_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
756 uint8 *res)
757 {
758 ossldata *od = c->ptr;
759
760 DES_ede3_cbc_encrypt(data, res, dlen,
761 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
762 (DES_cblock *) od->iv, 0);
763 return 0;
764 }
765
766 /* CAST5 */
767
768 static int
ossl_cast_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)769 ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
770 {
771 ossldata *od = c->ptr;
772 unsigned bs = gen_ossl_block_size(c);
773
774 CAST_set_key(&od->u.cast_key, klen, key);
775 if (iv)
776 memcpy(od->iv, iv, bs);
777 else
778 memset(od->iv, 0, bs);
779 return 0;
780 }
781
782 static int
ossl_cast_ecb_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)783 ossl_cast_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
784 {
785 unsigned bs = gen_ossl_block_size(c);
786 ossldata *od = c->ptr;
787 const uint8 *end = data + dlen - bs;
788
789 for (; data <= end; data += bs, res += bs)
790 CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_ENCRYPT);
791 return 0;
792 }
793
794 static int
ossl_cast_ecb_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)795 ossl_cast_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
796 {
797 unsigned bs = gen_ossl_block_size(c);
798 ossldata *od = c->ptr;
799 const uint8 *end = data + dlen - bs;
800
801 for (; data <= end; data += bs, res += bs)
802 CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_DECRYPT);
803 return 0;
804 }
805
806 static int
ossl_cast_cbc_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)807 ossl_cast_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
808 {
809 ossldata *od = c->ptr;
810
811 CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_ENCRYPT);
812 return 0;
813 }
814
815 static int
ossl_cast_cbc_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)816 ossl_cast_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
817 {
818 ossldata *od = c->ptr;
819
820 CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_DECRYPT);
821 return 0;
822 }
823
824 /* AES */
825
826 static int
ossl_aes_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)827 ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
828 {
829 ossldata *od = c->ptr;
830 unsigned bs = gen_ossl_block_size(c);
831
832 if (klen <= 128 / 8)
833 od->klen = 128 / 8;
834 else if (klen <= 192 / 8)
835 od->klen = 192 / 8;
836 else if (klen <= 256 / 8)
837 od->klen = 256 / 8;
838 else
839 return PXE_KEY_TOO_BIG;
840
841 memcpy(od->key, key, klen);
842
843 if (iv)
844 memcpy(od->iv, iv, bs);
845 else
846 memset(od->iv, 0, bs);
847 return 0;
848 }
849
850 static int
ossl_aes_key_init(ossldata * od,int type)851 ossl_aes_key_init(ossldata *od, int type)
852 {
853 int err;
854
855 /*
856 * Strong key support could be missing on some openssl installations. We
857 * must check return value from set key function.
858 */
859 if (type == AES_ENCRYPT)
860 err = AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
861 else
862 err = AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
863
864 if (err == 0)
865 {
866 od->init = 1;
867 return 0;
868 }
869 od->init = 0;
870 return PXE_KEY_TOO_BIG;
871 }
872
873 static int
ossl_aes_ecb_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)874 ossl_aes_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
875 uint8 *res)
876 {
877 unsigned bs = gen_ossl_block_size(c);
878 ossldata *od = c->ptr;
879 const uint8 *end = data + dlen - bs;
880 int err;
881
882 if (!od->init)
883 if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0)
884 return err;
885
886 for (; data <= end; data += bs, res += bs)
887 AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
888 return 0;
889 }
890
891 static int
ossl_aes_ecb_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)892 ossl_aes_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
893 uint8 *res)
894 {
895 unsigned bs = gen_ossl_block_size(c);
896 ossldata *od = c->ptr;
897 const uint8 *end = data + dlen - bs;
898 int err;
899
900 if (!od->init)
901 if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0)
902 return err;
903
904 for (; data <= end; data += bs, res += bs)
905 AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
906 return 0;
907 }
908
909 static int
ossl_aes_cbc_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)910 ossl_aes_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
911 uint8 *res)
912 {
913 ossldata *od = c->ptr;
914 int err;
915
916 if (!od->init)
917 if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0)
918 return err;
919
920 AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
921 return 0;
922 }
923
924 static int
ossl_aes_cbc_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)925 ossl_aes_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
926 uint8 *res)
927 {
928 ossldata *od = c->ptr;
929 int err;
930
931 if (!od->init)
932 if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0)
933 return err;
934
935 AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
936 return 0;
937 }
938
939 /*
940 * aliases
941 */
942
943 static PX_Alias ossl_aliases[] = {
944 {"bf", "bf-cbc"},
945 {"blowfish", "bf-cbc"},
946 {"blowfish-cbc", "bf-cbc"},
947 {"blowfish-ecb", "bf-ecb"},
948 {"blowfish-cfb", "bf-cfb"},
949 {"des", "des-cbc"},
950 {"3des", "des3-cbc"},
951 {"3des-ecb", "des3-ecb"},
952 {"3des-cbc", "des3-cbc"},
953 {"cast5", "cast5-cbc"},
954 {"aes", "aes-cbc"},
955 {"rijndael", "aes-cbc"},
956 {"rijndael-cbc", "aes-cbc"},
957 {"rijndael-ecb", "aes-ecb"},
958 {NULL}
959 };
960
961 static const struct ossl_cipher ossl_bf_cbc = {
962 bf_init, bf_cbc_encrypt, bf_cbc_decrypt,
963 64 / 8, 448 / 8, 0
964 };
965
966 static const struct ossl_cipher ossl_bf_ecb = {
967 bf_init, bf_ecb_encrypt, bf_ecb_decrypt,
968 64 / 8, 448 / 8, 0
969 };
970
971 static const struct ossl_cipher ossl_bf_cfb = {
972 bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt,
973 64 / 8, 448 / 8, 1
974 };
975
976 static const struct ossl_cipher ossl_des_ecb = {
977 ossl_des_init, ossl_des_ecb_encrypt, ossl_des_ecb_decrypt,
978 64 / 8, 64 / 8, 0
979 };
980
981 static const struct ossl_cipher ossl_des_cbc = {
982 ossl_des_init, ossl_des_cbc_encrypt, ossl_des_cbc_decrypt,
983 64 / 8, 64 / 8, 0
984 };
985
986 static const struct ossl_cipher ossl_des3_ecb = {
987 ossl_des3_init, ossl_des3_ecb_encrypt, ossl_des3_ecb_decrypt,
988 64 / 8, 192 / 8, 0
989 };
990
991 static const struct ossl_cipher ossl_des3_cbc = {
992 ossl_des3_init, ossl_des3_cbc_encrypt, ossl_des3_cbc_decrypt,
993 64 / 8, 192 / 8, 0
994 };
995
996 static const struct ossl_cipher ossl_cast_ecb = {
997 ossl_cast_init, ossl_cast_ecb_encrypt, ossl_cast_ecb_decrypt,
998 64 / 8, 128 / 8, 0
999 };
1000
1001 static const struct ossl_cipher ossl_cast_cbc = {
1002 ossl_cast_init, ossl_cast_cbc_encrypt, ossl_cast_cbc_decrypt,
1003 64 / 8, 128 / 8, 0
1004 };
1005
1006 static const struct ossl_cipher ossl_aes_ecb = {
1007 ossl_aes_init, ossl_aes_ecb_encrypt, ossl_aes_ecb_decrypt,
1008 128 / 8, 256 / 8, 0
1009 };
1010
1011 static const struct ossl_cipher ossl_aes_cbc = {
1012 ossl_aes_init, ossl_aes_cbc_encrypt, ossl_aes_cbc_decrypt,
1013 128 / 8, 256 / 8, 0
1014 };
1015
1016 /*
1017 * Special handlers
1018 */
1019 struct ossl_cipher_lookup
1020 {
1021 const char *name;
1022 const struct ossl_cipher *ciph;
1023 };
1024
1025 static const struct ossl_cipher_lookup ossl_cipher_types[] = {
1026 {"bf-cbc", &ossl_bf_cbc},
1027 {"bf-ecb", &ossl_bf_ecb},
1028 {"bf-cfb", &ossl_bf_cfb},
1029 {"des-ecb", &ossl_des_ecb},
1030 {"des-cbc", &ossl_des_cbc},
1031 {"des3-ecb", &ossl_des3_ecb},
1032 {"des3-cbc", &ossl_des3_cbc},
1033 {"cast5-ecb", &ossl_cast_ecb},
1034 {"cast5-cbc", &ossl_cast_cbc},
1035 {"aes-ecb", &ossl_aes_ecb},
1036 {"aes-cbc", &ossl_aes_cbc},
1037 {NULL}
1038 };
1039
1040 /* PUBLIC functions */
1041
1042 int
px_find_cipher(const char * name,PX_Cipher ** res)1043 px_find_cipher(const char *name, PX_Cipher **res)
1044 {
1045 const struct ossl_cipher_lookup *i;
1046 PX_Cipher *c = NULL;
1047 ossldata *od;
1048
1049 name = px_resolve_alias(ossl_aliases, name);
1050 for (i = ossl_cipher_types; i->name; i++)
1051 if (strcmp(i->name, name) == 0)
1052 break;
1053 if (i->name == NULL)
1054 return PXE_NO_CIPHER;
1055
1056 od = px_alloc(sizeof(*od));
1057 memset(od, 0, sizeof(*od));
1058 od->ciph = i->ciph;
1059
1060 c = px_alloc(sizeof(*c));
1061 c->block_size = gen_ossl_block_size;
1062 c->key_size = gen_ossl_key_size;
1063 c->iv_size = gen_ossl_iv_size;
1064 c->free = gen_ossl_free;
1065 c->init = od->ciph->init;
1066 c->encrypt = od->ciph->encrypt;
1067 c->decrypt = od->ciph->decrypt;
1068 c->ptr = od;
1069
1070 *res = c;
1071 return 0;
1072 }
1073
1074
1075 static int openssl_random_init = 0;
1076
1077 /*
1078 * OpenSSL random should re-feeded occasionally. From /dev/urandom
1079 * preferably.
1080 */
1081 static void
init_openssl_rand(void)1082 init_openssl_rand(void)
1083 {
1084 if (RAND_get_rand_method() == NULL)
1085 {
1086 #ifdef HAVE_RAND_OPENSSL
1087 RAND_set_rand_method(RAND_OpenSSL());
1088 #else
1089 RAND_set_rand_method(RAND_SSLeay());
1090 #endif
1091 }
1092 openssl_random_init = 1;
1093 }
1094
1095 int
px_get_random_bytes(uint8 * dst,unsigned count)1096 px_get_random_bytes(uint8 *dst, unsigned count)
1097 {
1098 int res;
1099
1100 if (!openssl_random_init)
1101 init_openssl_rand();
1102
1103 res = RAND_bytes(dst, count);
1104 if (res == 1)
1105 return count;
1106
1107 return PXE_OSSL_RAND_ERROR;
1108 }
1109
1110 int
px_add_entropy(const uint8 * data,unsigned count)1111 px_add_entropy(const uint8 *data, unsigned count)
1112 {
1113 /*
1114 * estimate 0 bits
1115 */
1116 RAND_add(data, count, 0);
1117 return 0;
1118 }
1119