00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "postgres.h"
00033
00034 #include <time.h>
00035
00036 #include "px.h"
00037 #include "md5.h"
00038 #include "sha1.h"
00039 #include "blf.h"
00040 #include "rijndael.h"
00041 #include "fortuna.h"
00042
00043
00044
00045
00046 #define SYSTEM_RESEED_MIN (20*60)
00047
00048
00049
00050 #define SYSTEM_RESEED_CHECK_TIME (10*60)
00051
00052
00053
00054 #define SYSTEM_RESEED_CHANCE (4)
00055
00056
00057
00058
00059 #define SYSTEM_RESEED_MAX (12*60*60)
00060
00061
00062 #ifndef MD5_DIGEST_LENGTH
00063 #define MD5_DIGEST_LENGTH 16
00064 #endif
00065
00066 #ifndef SHA1_DIGEST_LENGTH
00067 #ifdef SHA1_RESULTLEN
00068 #define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
00069 #else
00070 #define SHA1_DIGEST_LENGTH 20
00071 #endif
00072 #endif
00073
00074 #define SHA1_BLOCK_SIZE 64
00075 #define MD5_BLOCK_SIZE 64
00076
00077 static void init_md5(PX_MD *h);
00078 static void init_sha1(PX_MD *h);
00079
00080 void init_sha224(PX_MD *h);
00081 void init_sha256(PX_MD *h);
00082 void init_sha384(PX_MD *h);
00083 void init_sha512(PX_MD *h);
00084
00085 struct int_digest
00086 {
00087 char *name;
00088 void (*init) (PX_MD *h);
00089 };
00090
00091 static const struct int_digest
00092 int_digest_list[] = {
00093 {"md5", init_md5},
00094 {"sha1", init_sha1},
00095 {"sha224", init_sha224},
00096 {"sha256", init_sha256},
00097 {"sha384", init_sha384},
00098 {"sha512", init_sha512},
00099 {NULL, NULL}
00100 };
00101
00102
00103
00104 static unsigned
00105 int_md5_len(PX_MD *h)
00106 {
00107 return MD5_DIGEST_LENGTH;
00108 }
00109
00110 static unsigned
00111 int_md5_block_len(PX_MD *h)
00112 {
00113 return MD5_BLOCK_SIZE;
00114 }
00115
00116 static void
00117 int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
00118 {
00119 MD5_CTX *ctx = (MD5_CTX *) h->p.ptr;
00120
00121 MD5Update(ctx, data, dlen);
00122 }
00123
00124 static void
00125 int_md5_reset(PX_MD *h)
00126 {
00127 MD5_CTX *ctx = (MD5_CTX *) h->p.ptr;
00128
00129 MD5Init(ctx);
00130 }
00131
00132 static void
00133 int_md5_finish(PX_MD *h, uint8 *dst)
00134 {
00135 MD5_CTX *ctx = (MD5_CTX *) h->p.ptr;
00136
00137 MD5Final(dst, ctx);
00138 }
00139
00140 static void
00141 int_md5_free(PX_MD *h)
00142 {
00143 MD5_CTX *ctx = (MD5_CTX *) h->p.ptr;
00144
00145 memset(ctx, 0, sizeof(*ctx));
00146 px_free(ctx);
00147 px_free(h);
00148 }
00149
00150
00151
00152 static unsigned
00153 int_sha1_len(PX_MD *h)
00154 {
00155 return SHA1_DIGEST_LENGTH;
00156 }
00157
00158 static unsigned
00159 int_sha1_block_len(PX_MD *h)
00160 {
00161 return SHA1_BLOCK_SIZE;
00162 }
00163
00164 static void
00165 int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
00166 {
00167 SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr;
00168
00169 SHA1Update(ctx, data, dlen);
00170 }
00171
00172 static void
00173 int_sha1_reset(PX_MD *h)
00174 {
00175 SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr;
00176
00177 SHA1Init(ctx);
00178 }
00179
00180 static void
00181 int_sha1_finish(PX_MD *h, uint8 *dst)
00182 {
00183 SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr;
00184
00185 SHA1Final(dst, ctx);
00186 }
00187
00188 static void
00189 int_sha1_free(PX_MD *h)
00190 {
00191 SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr;
00192
00193 memset(ctx, 0, sizeof(*ctx));
00194 px_free(ctx);
00195 px_free(h);
00196 }
00197
00198
00199
00200 static void
00201 init_md5(PX_MD *md)
00202 {
00203 MD5_CTX *ctx;
00204
00205 ctx = px_alloc(sizeof(*ctx));
00206 memset(ctx, 0, sizeof(*ctx));
00207
00208 md->p.ptr = ctx;
00209
00210 md->result_size = int_md5_len;
00211 md->block_size = int_md5_block_len;
00212 md->reset = int_md5_reset;
00213 md->update = int_md5_update;
00214 md->finish = int_md5_finish;
00215 md->free = int_md5_free;
00216
00217 md->reset(md);
00218 }
00219
00220 static void
00221 init_sha1(PX_MD *md)
00222 {
00223 SHA1_CTX *ctx;
00224
00225 ctx = px_alloc(sizeof(*ctx));
00226 memset(ctx, 0, sizeof(*ctx));
00227
00228 md->p.ptr = ctx;
00229
00230 md->result_size = int_sha1_len;
00231 md->block_size = int_sha1_block_len;
00232 md->reset = int_sha1_reset;
00233 md->update = int_sha1_update;
00234 md->finish = int_sha1_finish;
00235 md->free = int_sha1_free;
00236
00237 md->reset(md);
00238 }
00239
00240
00241
00242
00243
00244 #define INT_MAX_KEY (512/8)
00245 #define INT_MAX_IV (128/8)
00246
00247 struct int_ctx
00248 {
00249 uint8 keybuf[INT_MAX_KEY];
00250 uint8 iv[INT_MAX_IV];
00251 union
00252 {
00253 BlowfishContext bf;
00254 rijndael_ctx rj;
00255 } ctx;
00256 unsigned keylen;
00257 int is_init;
00258 int mode;
00259 };
00260
00261 static void
00262 intctx_free(PX_Cipher *c)
00263 {
00264 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00265
00266 if (cx)
00267 {
00268 memset(cx, 0, sizeof *cx);
00269 px_free(cx);
00270 }
00271 px_free(c);
00272 }
00273
00274
00275
00276
00277
00278 #define MODE_ECB 0
00279 #define MODE_CBC 1
00280
00281 static unsigned
00282 rj_block_size(PX_Cipher *c)
00283 {
00284 return 128 / 8;
00285 }
00286
00287 static unsigned
00288 rj_key_size(PX_Cipher *c)
00289 {
00290 return 256 / 8;
00291 }
00292
00293 static unsigned
00294 rj_iv_size(PX_Cipher *c)
00295 {
00296 return 128 / 8;
00297 }
00298
00299 static int
00300 rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
00301 {
00302 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00303
00304 if (klen <= 128 / 8)
00305 cx->keylen = 128 / 8;
00306 else if (klen <= 192 / 8)
00307 cx->keylen = 192 / 8;
00308 else if (klen <= 256 / 8)
00309 cx->keylen = 256 / 8;
00310 else
00311 return PXE_KEY_TOO_BIG;
00312
00313 memcpy(&cx->keybuf, key, klen);
00314
00315 if (iv)
00316 memcpy(cx->iv, iv, 128 / 8);
00317
00318 return 0;
00319 }
00320
00321 static int
00322 rj_real_init(struct int_ctx * cx, int dir)
00323 {
00324 aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
00325 return 0;
00326 }
00327
00328 static int
00329 rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
00330 {
00331 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00332
00333 if (!cx->is_init)
00334 {
00335 if (rj_real_init(cx, 1))
00336 return PXE_CIPHER_INIT;
00337 }
00338
00339 if (dlen == 0)
00340 return 0;
00341
00342 if (dlen & 15)
00343 return PXE_NOTBLOCKSIZE;
00344
00345 memcpy(res, data, dlen);
00346
00347 if (cx->mode == MODE_CBC)
00348 {
00349 aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
00350 memcpy(cx->iv, res + dlen - 16, 16);
00351 }
00352 else
00353 aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
00354
00355 return 0;
00356 }
00357
00358 static int
00359 rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
00360 {
00361 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00362
00363 if (!cx->is_init)
00364 if (rj_real_init(cx, 0))
00365 return PXE_CIPHER_INIT;
00366
00367 if (dlen == 0)
00368 return 0;
00369
00370 if (dlen & 15)
00371 return PXE_NOTBLOCKSIZE;
00372
00373 memcpy(res, data, dlen);
00374
00375 if (cx->mode == MODE_CBC)
00376 {
00377 aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
00378 memcpy(cx->iv, data + dlen - 16, 16);
00379 }
00380 else
00381 aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
00382
00383 return 0;
00384 }
00385
00386
00387
00388
00389
00390 static PX_Cipher *
00391 rj_load(int mode)
00392 {
00393 PX_Cipher *c;
00394 struct int_ctx *cx;
00395
00396 c = px_alloc(sizeof *c);
00397 memset(c, 0, sizeof *c);
00398
00399 c->block_size = rj_block_size;
00400 c->key_size = rj_key_size;
00401 c->iv_size = rj_iv_size;
00402 c->init = rj_init;
00403 c->encrypt = rj_encrypt;
00404 c->decrypt = rj_decrypt;
00405 c->free = intctx_free;
00406
00407 cx = px_alloc(sizeof *cx);
00408 memset(cx, 0, sizeof *cx);
00409 cx->mode = mode;
00410
00411 c->ptr = cx;
00412 return c;
00413 }
00414
00415
00416
00417
00418
00419 static unsigned
00420 bf_block_size(PX_Cipher *c)
00421 {
00422 return 8;
00423 }
00424
00425 static unsigned
00426 bf_key_size(PX_Cipher *c)
00427 {
00428 return 448 / 8;
00429 }
00430
00431 static unsigned
00432 bf_iv_size(PX_Cipher *c)
00433 {
00434 return 8;
00435 }
00436
00437 static int
00438 bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
00439 {
00440 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00441
00442 blowfish_setkey(&cx->ctx.bf, key, klen);
00443 if (iv)
00444 blowfish_setiv(&cx->ctx.bf, iv);
00445
00446 return 0;
00447 }
00448
00449 static int
00450 bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
00451 {
00452 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00453 BlowfishContext *bfctx = &cx->ctx.bf;
00454
00455 if (dlen == 0)
00456 return 0;
00457
00458 if (dlen & 7)
00459 return PXE_NOTBLOCKSIZE;
00460
00461 memcpy(res, data, dlen);
00462 switch (cx->mode)
00463 {
00464 case MODE_ECB:
00465 blowfish_encrypt_ecb(res, dlen, bfctx);
00466 break;
00467 case MODE_CBC:
00468 blowfish_encrypt_cbc(res, dlen, bfctx);
00469 break;
00470 }
00471 return 0;
00472 }
00473
00474 static int
00475 bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
00476 {
00477 struct int_ctx *cx = (struct int_ctx *) c->ptr;
00478 BlowfishContext *bfctx = &cx->ctx.bf;
00479
00480 if (dlen == 0)
00481 return 0;
00482
00483 if (dlen & 7)
00484 return PXE_NOTBLOCKSIZE;
00485
00486 memcpy(res, data, dlen);
00487 switch (cx->mode)
00488 {
00489 case MODE_ECB:
00490 blowfish_decrypt_ecb(res, dlen, bfctx);
00491 break;
00492 case MODE_CBC:
00493 blowfish_decrypt_cbc(res, dlen, bfctx);
00494 break;
00495 }
00496 return 0;
00497 }
00498
00499 static PX_Cipher *
00500 bf_load(int mode)
00501 {
00502 PX_Cipher *c;
00503 struct int_ctx *cx;
00504
00505 c = px_alloc(sizeof *c);
00506 memset(c, 0, sizeof *c);
00507
00508 c->block_size = bf_block_size;
00509 c->key_size = bf_key_size;
00510 c->iv_size = bf_iv_size;
00511 c->init = bf_init;
00512 c->encrypt = bf_encrypt;
00513 c->decrypt = bf_decrypt;
00514 c->free = intctx_free;
00515
00516 cx = px_alloc(sizeof *cx);
00517 memset(cx, 0, sizeof *cx);
00518 cx->mode = mode;
00519 c->ptr = cx;
00520 return c;
00521 }
00522
00523
00524
00525 static PX_Cipher *
00526 rj_128_ecb(void)
00527 {
00528 return rj_load(MODE_ECB);
00529 }
00530
00531 static PX_Cipher *
00532 rj_128_cbc(void)
00533 {
00534 return rj_load(MODE_CBC);
00535 }
00536
00537 static PX_Cipher *
00538 bf_ecb_load(void)
00539 {
00540 return bf_load(MODE_ECB);
00541 }
00542
00543 static PX_Cipher *
00544 bf_cbc_load(void)
00545 {
00546 return bf_load(MODE_CBC);
00547 }
00548
00549 struct int_cipher
00550 {
00551 char *name;
00552 PX_Cipher *(*load) (void);
00553 };
00554
00555 static const struct int_cipher
00556 int_ciphers[] = {
00557 {"bf-cbc", bf_cbc_load},
00558 {"bf-ecb", bf_ecb_load},
00559 {"aes-128-cbc", rj_128_cbc},
00560 {"aes-128-ecb", rj_128_ecb},
00561 {NULL, NULL}
00562 };
00563
00564 static const PX_Alias int_aliases[] = {
00565 {"bf", "bf-cbc"},
00566 {"blowfish", "bf-cbc"},
00567 {"aes", "aes-128-cbc"},
00568 {"aes-ecb", "aes-128-ecb"},
00569 {"aes-cbc", "aes-128-cbc"},
00570 {"aes-128", "aes-128-cbc"},
00571 {"rijndael", "aes-128-cbc"},
00572 {"rijndael-128", "aes-128-cbc"},
00573 {NULL, NULL}
00574 };
00575
00576
00577
00578 int
00579 px_find_digest(const char *name, PX_MD **res)
00580 {
00581 const struct int_digest *p;
00582 PX_MD *h;
00583
00584 for (p = int_digest_list; p->name; p++)
00585 if (pg_strcasecmp(p->name, name) == 0)
00586 {
00587 h = px_alloc(sizeof(*h));
00588 p->init(h);
00589
00590 *res = h;
00591
00592 return 0;
00593 }
00594 return PXE_NO_HASH;
00595 }
00596
00597 int
00598 px_find_cipher(const char *name, PX_Cipher **res)
00599 {
00600 int i;
00601 PX_Cipher *c = NULL;
00602
00603 name = px_resolve_alias(int_aliases, name);
00604
00605 for (i = 0; int_ciphers[i].name; i++)
00606 if (strcmp(int_ciphers[i].name, name) == 0)
00607 {
00608 c = int_ciphers[i].load();
00609 break;
00610 }
00611
00612 if (c == NULL)
00613 return PXE_NO_CIPHER;
00614
00615 *res = c;
00616 return 0;
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626 int
00627 px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
00628 {
00629 return px_get_random_bytes(dst, count);
00630 }
00631
00632 static time_t seed_time = 0;
00633 static time_t check_time = 0;
00634
00635 static void
00636 system_reseed(void)
00637 {
00638 uint8 buf[1024];
00639 int n;
00640 time_t t;
00641 int skip = 1;
00642
00643 t = time(NULL);
00644
00645 if (seed_time == 0)
00646 skip = 0;
00647 else if ((t - seed_time) < SYSTEM_RESEED_MIN)
00648 skip = 1;
00649 else if ((t - seed_time) > SYSTEM_RESEED_MAX)
00650 skip = 0;
00651 else if (check_time == 0 ||
00652 (t - check_time) > SYSTEM_RESEED_CHECK_TIME)
00653 {
00654 check_time = t;
00655
00656
00657 px_get_random_bytes(buf, 1);
00658 skip = buf[0] >= SYSTEM_RESEED_CHANCE;
00659 }
00660
00661 memset(buf, 0, sizeof(buf));
00662
00663 if (skip)
00664 return;
00665
00666 n = px_acquire_system_randomness(buf);
00667 if (n > 0)
00668 fortuna_add_entropy(buf, n);
00669
00670 seed_time = t;
00671 memset(buf, 0, sizeof(buf));
00672 }
00673
00674 int
00675 px_get_random_bytes(uint8 *dst, unsigned count)
00676 {
00677 system_reseed();
00678 fortuna_get_bytes(count, dst);
00679 return 0;
00680 }
00681
00682 int
00683 px_add_entropy(const uint8 *data, unsigned count)
00684 {
00685 system_reseed();
00686 fortuna_add_entropy(data, count);
00687 return 0;
00688 }