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