1 /*
2  * internal.c
3  *		Wrapper for builtin functions
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/internal.c
30  */
31 
32 #include "postgres.h"
33 
34 #include <time.h>
35 
36 #include "px.h"
37 #include "md5.h"
38 #include "sha1.h"
39 #include "blf.h"
40 #include "rijndael.h"
41 
42 /*
43  * System reseeds should be separated at least this much.
44  */
45 #define SYSTEM_RESEED_MIN			(20*60) /* 20 min */
46 /*
47  * How often to roll dice.
48  */
49 #define SYSTEM_RESEED_CHECK_TIME	(10*60) /* 10 min */
50 /*
51  * The chance is x/256 that the reseed happens.
52  */
53 #define SYSTEM_RESEED_CHANCE		(4) /* 256/4 * 10min ~ 10h */
54 
55 /*
56  * If this much time has passed, force reseed.
57  */
58 #define SYSTEM_RESEED_MAX			(12*60*60)	/* 12h */
59 
60 
61 #ifndef MD5_DIGEST_LENGTH
62 #define MD5_DIGEST_LENGTH 16
63 #endif
64 
65 #ifndef SHA1_DIGEST_LENGTH
66 #ifdef SHA1_RESULTLEN
67 #define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
68 #else
69 #define SHA1_DIGEST_LENGTH 20
70 #endif
71 #endif
72 
73 #define SHA1_BLOCK_SIZE 64
74 #define MD5_BLOCK_SIZE 64
75 
76 static void init_md5(PX_MD *h);
77 static void init_sha1(PX_MD *h);
78 
79 void		init_sha224(PX_MD *h);
80 void		init_sha256(PX_MD *h);
81 void		init_sha384(PX_MD *h);
82 void		init_sha512(PX_MD *h);
83 
84 struct int_digest
85 {
86 	char	   *name;
87 	void		(*init) (PX_MD *h);
88 };
89 
90 static const struct int_digest
91 			int_digest_list[] = {
92 	{"md5", init_md5},
93 	{"sha1", init_sha1},
94 	{"sha224", init_sha224},
95 	{"sha256", init_sha256},
96 	{"sha384", init_sha384},
97 	{"sha512", init_sha512},
98 	{NULL, NULL}
99 };
100 
101 /* MD5 */
102 
103 static unsigned
int_md5_len(PX_MD * h)104 int_md5_len(PX_MD *h)
105 {
106 	return MD5_DIGEST_LENGTH;
107 }
108 
109 static unsigned
int_md5_block_len(PX_MD * h)110 int_md5_block_len(PX_MD *h)
111 {
112 	return MD5_BLOCK_SIZE;
113 }
114 
115 static void
int_md5_update(PX_MD * h,const uint8 * data,unsigned dlen)116 int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
117 {
118 	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
119 
120 	MD5Update(ctx, data, dlen);
121 }
122 
123 static void
int_md5_reset(PX_MD * h)124 int_md5_reset(PX_MD *h)
125 {
126 	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
127 
128 	MD5Init(ctx);
129 }
130 
131 static void
int_md5_finish(PX_MD * h,uint8 * dst)132 int_md5_finish(PX_MD *h, uint8 *dst)
133 {
134 	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
135 
136 	MD5Final(dst, ctx);
137 }
138 
139 static void
int_md5_free(PX_MD * h)140 int_md5_free(PX_MD *h)
141 {
142 	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
143 
144 	px_memset(ctx, 0, sizeof(*ctx));
145 	px_free(ctx);
146 	px_free(h);
147 }
148 
149 /* SHA1 */
150 
151 static unsigned
int_sha1_len(PX_MD * h)152 int_sha1_len(PX_MD *h)
153 {
154 	return SHA1_DIGEST_LENGTH;
155 }
156 
157 static unsigned
int_sha1_block_len(PX_MD * h)158 int_sha1_block_len(PX_MD *h)
159 {
160 	return SHA1_BLOCK_SIZE;
161 }
162 
163 static void
int_sha1_update(PX_MD * h,const uint8 * data,unsigned dlen)164 int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
165 {
166 	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
167 
168 	SHA1Update(ctx, data, dlen);
169 }
170 
171 static void
int_sha1_reset(PX_MD * h)172 int_sha1_reset(PX_MD *h)
173 {
174 	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
175 
176 	SHA1Init(ctx);
177 }
178 
179 static void
int_sha1_finish(PX_MD * h,uint8 * dst)180 int_sha1_finish(PX_MD *h, uint8 *dst)
181 {
182 	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
183 
184 	SHA1Final(dst, ctx);
185 }
186 
187 static void
int_sha1_free(PX_MD * h)188 int_sha1_free(PX_MD *h)
189 {
190 	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
191 
192 	px_memset(ctx, 0, sizeof(*ctx));
193 	px_free(ctx);
194 	px_free(h);
195 }
196 
197 /* init functions */
198 
199 static void
init_md5(PX_MD * md)200 init_md5(PX_MD *md)
201 {
202 	MD5_CTX    *ctx;
203 
204 	ctx = px_alloc(sizeof(*ctx));
205 	memset(ctx, 0, sizeof(*ctx));
206 
207 	md->p.ptr = ctx;
208 
209 	md->result_size = int_md5_len;
210 	md->block_size = int_md5_block_len;
211 	md->reset = int_md5_reset;
212 	md->update = int_md5_update;
213 	md->finish = int_md5_finish;
214 	md->free = int_md5_free;
215 
216 	md->reset(md);
217 }
218 
219 static void
init_sha1(PX_MD * md)220 init_sha1(PX_MD *md)
221 {
222 	SHA1_CTX   *ctx;
223 
224 	ctx = px_alloc(sizeof(*ctx));
225 	memset(ctx, 0, sizeof(*ctx));
226 
227 	md->p.ptr = ctx;
228 
229 	md->result_size = int_sha1_len;
230 	md->block_size = int_sha1_block_len;
231 	md->reset = int_sha1_reset;
232 	md->update = int_sha1_update;
233 	md->finish = int_sha1_finish;
234 	md->free = int_sha1_free;
235 
236 	md->reset(md);
237 }
238 
239 /*
240  * ciphers generally
241  */
242 
243 #define INT_MAX_KEY		(512/8)
244 #define INT_MAX_IV		(128/8)
245 
246 struct int_ctx
247 {
248 	uint8		keybuf[INT_MAX_KEY];
249 	uint8		iv[INT_MAX_IV];
250 	union
251 	{
252 		BlowfishContext bf;
253 		rijndael_ctx rj;
254 	}			ctx;
255 	unsigned	keylen;
256 	int			is_init;
257 	int			mode;
258 };
259 
260 static void
intctx_free(PX_Cipher * c)261 intctx_free(PX_Cipher *c)
262 {
263 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
264 
265 	if (cx)
266 	{
267 		px_memset(cx, 0, sizeof *cx);
268 		px_free(cx);
269 	}
270 	px_free(c);
271 }
272 
273 /*
274  * AES/rijndael
275  */
276 
277 #define MODE_ECB 0
278 #define MODE_CBC 1
279 
280 static unsigned
rj_block_size(PX_Cipher * c)281 rj_block_size(PX_Cipher *c)
282 {
283 	return 128 / 8;
284 }
285 
286 static unsigned
rj_key_size(PX_Cipher * c)287 rj_key_size(PX_Cipher *c)
288 {
289 	return 256 / 8;
290 }
291 
292 static unsigned
rj_iv_size(PX_Cipher * c)293 rj_iv_size(PX_Cipher *c)
294 {
295 	return 128 / 8;
296 }
297 
298 static int
rj_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)299 rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
300 {
301 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
302 
303 	if (klen <= 128 / 8)
304 		cx->keylen = 128 / 8;
305 	else if (klen <= 192 / 8)
306 		cx->keylen = 192 / 8;
307 	else if (klen <= 256 / 8)
308 		cx->keylen = 256 / 8;
309 	else
310 		return PXE_KEY_TOO_BIG;
311 
312 	memcpy(&cx->keybuf, key, klen);
313 
314 	if (iv)
315 		memcpy(cx->iv, iv, 128 / 8);
316 
317 	return 0;
318 }
319 
320 static int
rj_real_init(struct int_ctx * cx,int dir)321 rj_real_init(struct int_ctx *cx, int dir)
322 {
323 	aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
324 	return 0;
325 }
326 
327 static int
rj_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)328 rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
329 {
330 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
331 
332 	if (!cx->is_init)
333 	{
334 		if (rj_real_init(cx, 1))
335 			return PXE_CIPHER_INIT;
336 	}
337 
338 	if (dlen == 0)
339 		return 0;
340 
341 	if (dlen & 15)
342 		return PXE_NOTBLOCKSIZE;
343 
344 	memcpy(res, data, dlen);
345 
346 	if (cx->mode == MODE_CBC)
347 	{
348 		aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
349 		memcpy(cx->iv, res + dlen - 16, 16);
350 	}
351 	else
352 		aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
353 
354 	return 0;
355 }
356 
357 static int
rj_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)358 rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
359 {
360 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
361 
362 	if (!cx->is_init)
363 		if (rj_real_init(cx, 0))
364 			return PXE_CIPHER_INIT;
365 
366 	if (dlen == 0)
367 		return 0;
368 
369 	if (dlen & 15)
370 		return PXE_NOTBLOCKSIZE;
371 
372 	memcpy(res, data, dlen);
373 
374 	if (cx->mode == MODE_CBC)
375 	{
376 		aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
377 		memcpy(cx->iv, data + dlen - 16, 16);
378 	}
379 	else
380 		aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
381 
382 	return 0;
383 }
384 
385 /*
386  * initializers
387  */
388 
389 static PX_Cipher *
rj_load(int mode)390 rj_load(int mode)
391 {
392 	PX_Cipher  *c;
393 	struct int_ctx *cx;
394 
395 	c = px_alloc(sizeof *c);
396 	memset(c, 0, sizeof *c);
397 
398 	c->block_size = rj_block_size;
399 	c->key_size = rj_key_size;
400 	c->iv_size = rj_iv_size;
401 	c->init = rj_init;
402 	c->encrypt = rj_encrypt;
403 	c->decrypt = rj_decrypt;
404 	c->free = intctx_free;
405 
406 	cx = px_alloc(sizeof *cx);
407 	memset(cx, 0, sizeof *cx);
408 	cx->mode = mode;
409 
410 	c->ptr = cx;
411 	return c;
412 }
413 
414 /*
415  * blowfish
416  */
417 
418 static unsigned
bf_block_size(PX_Cipher * c)419 bf_block_size(PX_Cipher *c)
420 {
421 	return 8;
422 }
423 
424 static unsigned
bf_key_size(PX_Cipher * c)425 bf_key_size(PX_Cipher *c)
426 {
427 	return 448 / 8;
428 }
429 
430 static unsigned
bf_iv_size(PX_Cipher * c)431 bf_iv_size(PX_Cipher *c)
432 {
433 	return 8;
434 }
435 
436 static int
bf_init(PX_Cipher * c,const uint8 * key,unsigned klen,const uint8 * iv)437 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
438 {
439 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
440 
441 	blowfish_setkey(&cx->ctx.bf, key, klen);
442 	if (iv)
443 		blowfish_setiv(&cx->ctx.bf, iv);
444 
445 	return 0;
446 }
447 
448 static int
bf_encrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)449 bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
450 {
451 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
452 	BlowfishContext *bfctx = &cx->ctx.bf;
453 
454 	if (dlen == 0)
455 		return 0;
456 
457 	if (dlen & 7)
458 		return PXE_NOTBLOCKSIZE;
459 
460 	memcpy(res, data, dlen);
461 	switch (cx->mode)
462 	{
463 		case MODE_ECB:
464 			blowfish_encrypt_ecb(res, dlen, bfctx);
465 			break;
466 		case MODE_CBC:
467 			blowfish_encrypt_cbc(res, dlen, bfctx);
468 			break;
469 	}
470 	return 0;
471 }
472 
473 static int
bf_decrypt(PX_Cipher * c,const uint8 * data,unsigned dlen,uint8 * res)474 bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
475 {
476 	struct int_ctx *cx = (struct int_ctx *) c->ptr;
477 	BlowfishContext *bfctx = &cx->ctx.bf;
478 
479 	if (dlen == 0)
480 		return 0;
481 
482 	if (dlen & 7)
483 		return PXE_NOTBLOCKSIZE;
484 
485 	memcpy(res, data, dlen);
486 	switch (cx->mode)
487 	{
488 		case MODE_ECB:
489 			blowfish_decrypt_ecb(res, dlen, bfctx);
490 			break;
491 		case MODE_CBC:
492 			blowfish_decrypt_cbc(res, dlen, bfctx);
493 			break;
494 	}
495 	return 0;
496 }
497 
498 static PX_Cipher *
bf_load(int mode)499 bf_load(int mode)
500 {
501 	PX_Cipher  *c;
502 	struct int_ctx *cx;
503 
504 	c = px_alloc(sizeof *c);
505 	memset(c, 0, sizeof *c);
506 
507 	c->block_size = bf_block_size;
508 	c->key_size = bf_key_size;
509 	c->iv_size = bf_iv_size;
510 	c->init = bf_init;
511 	c->encrypt = bf_encrypt;
512 	c->decrypt = bf_decrypt;
513 	c->free = intctx_free;
514 
515 	cx = px_alloc(sizeof *cx);
516 	memset(cx, 0, sizeof *cx);
517 	cx->mode = mode;
518 	c->ptr = cx;
519 	return c;
520 }
521 
522 /* ciphers */
523 
524 static PX_Cipher *
rj_128_ecb(void)525 rj_128_ecb(void)
526 {
527 	return rj_load(MODE_ECB);
528 }
529 
530 static PX_Cipher *
rj_128_cbc(void)531 rj_128_cbc(void)
532 {
533 	return rj_load(MODE_CBC);
534 }
535 
536 static PX_Cipher *
bf_ecb_load(void)537 bf_ecb_load(void)
538 {
539 	return bf_load(MODE_ECB);
540 }
541 
542 static PX_Cipher *
bf_cbc_load(void)543 bf_cbc_load(void)
544 {
545 	return bf_load(MODE_CBC);
546 }
547 
548 struct int_cipher
549 {
550 	char	   *name;
551 	PX_Cipher  *(*load) (void);
552 };
553 
554 static const struct int_cipher
555 			int_ciphers[] = {
556 	{"bf-cbc", bf_cbc_load},
557 	{"bf-ecb", bf_ecb_load},
558 	{"aes-128-cbc", rj_128_cbc},
559 	{"aes-128-ecb", rj_128_ecb},
560 	{NULL, NULL}
561 };
562 
563 static const PX_Alias int_aliases[] = {
564 	{"bf", "bf-cbc"},
565 	{"blowfish", "bf-cbc"},
566 	{"aes", "aes-128-cbc"},
567 	{"aes-ecb", "aes-128-ecb"},
568 	{"aes-cbc", "aes-128-cbc"},
569 	{"aes-128", "aes-128-cbc"},
570 	{"rijndael", "aes-128-cbc"},
571 	{"rijndael-128", "aes-128-cbc"},
572 	{NULL, NULL}
573 };
574 
575 /* PUBLIC FUNCTIONS */
576 
577 int
px_find_digest(const char * name,PX_MD ** res)578 px_find_digest(const char *name, PX_MD **res)
579 {
580 	const struct int_digest *p;
581 	PX_MD	   *h;
582 
583 	for (p = int_digest_list; p->name; p++)
584 		if (pg_strcasecmp(p->name, name) == 0)
585 		{
586 			h = px_alloc(sizeof(*h));
587 			p->init(h);
588 
589 			*res = h;
590 
591 			return 0;
592 		}
593 	return PXE_NO_HASH;
594 }
595 
596 int
px_find_cipher(const char * name,PX_Cipher ** res)597 px_find_cipher(const char *name, PX_Cipher **res)
598 {
599 	int			i;
600 	PX_Cipher  *c = NULL;
601 
602 	name = px_resolve_alias(int_aliases, name);
603 
604 	for (i = 0; int_ciphers[i].name; i++)
605 		if (strcmp(int_ciphers[i].name, name) == 0)
606 		{
607 			c = int_ciphers[i].load();
608 			break;
609 		}
610 
611 	if (c == NULL)
612 		return PXE_NO_CIPHER;
613 
614 	*res = c;
615 	return 0;
616 }
617