00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "system.h"
00030 #include "beecrypt.h"
00031
00032 #if defined(__LCLINT__)
00033
00034 # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
00035 typedef struct
00036 {
00037 unsigned long int __val[_SIGSET_NWORDS];
00038 } __sigset_t;
00039 #endif
00040
00041 #include "endianness.h"
00042 #include "entropy.h"
00043 #include "fips186.h"
00044 #include "hmacmd5.h"
00045 #include "hmacsha1.h"
00046 #include "hmacsha256.h"
00047 #include "md5.h"
00048 #include "mp32.h"
00049 #include "mtprng.h"
00050 #include "sha1.h"
00051 #include "sha256.h"
00052
00053 #include "aes.h"
00054 #include "blowfish.h"
00055 #include "blockmode.h"
00056
00057 #include "debug.h"
00058
00059
00060
00061 static entropySource entropySourceList[] =
00062 {
00063 #if WIN32
00064 { "wavein", entropy_wavein },
00065 { "console", entropy_console },
00066 { "wincrypt", entropy_wincrypt },
00067 #else
00068 # if HAVE_DEV_AUDIO
00069 { "audio", entropy_dev_audio },
00070 # endif
00071 # if HAVE_DEV_DSP
00072 { "dsp", entropy_dev_dsp },
00073 # endif
00074 # if HAVE_DEV_RANDOM
00075 { "random", entropy_dev_random },
00076 # endif
00077 # if HAVE_DEV_URANDOM
00078 { "urandom", entropy_dev_urandom },
00079 # endif
00080 # if HAVE_DEV_TTY
00081 { "tty", entropy_dev_tty },
00082 # endif
00083 #endif
00084 };
00085
00086
00087 #define ENTROPYSOURCES (sizeof(entropySourceList) / sizeof(entropySource))
00088
00089 int entropySourceCount()
00090 {
00091 return ENTROPYSOURCES;
00092 }
00093
00094 const entropySource* entropySourceGet(int index)
00095 {
00096 if ((index < 0) || (index >= ENTROPYSOURCES))
00097 return (const entropySource*) 0;
00098
00099 return entropySourceList+index;
00100 }
00101
00102
00103 const entropySource* entropySourceFind(const char* name)
00104 {
00105 register int index;
00106
00107 for (index = 0; index < ENTROPYSOURCES; index++)
00108 {
00109 if (strcmp(name, entropySourceList[index].name) == 0)
00110 return entropySourceList+index;
00111 }
00112 return (const entropySource*) 0;
00113 }
00114
00115
00116 const entropySource* entropySourceDefault()
00117 {
00118 const char* selection = getenv("BEECRYPT_ENTROPY");
00119
00120 if (selection)
00121 return entropySourceFind(selection);
00122 else if (ENTROPYSOURCES)
00123 return entropySourceList+0;
00124 else
00125 return (const entropySource*) 0;
00126 }
00127
00128
00129 int entropyGatherNext(uint32* data, int size)
00130 {
00131 const char* selection = getenv("BEECRYPT_ENTROPY");
00132
00133 if (selection)
00134 {
00135 const entropySource* ptr = entropySourceFind(selection);
00136
00137 if (ptr)
00138 return ptr->next(data, size);
00139 }
00140 else
00141 {
00142 register int index;
00143
00144 for (index = 0; index < ENTROPYSOURCES; index++)
00145 {
00146 if (entropySourceList[index].next(data, size) == 0)
00147 return 0;
00148 }
00149 }
00150 return -1;
00151 }
00152
00153
00154
00155
00156 static const randomGenerator* randomGeneratorList[] =
00157 {
00158 &fips186prng,
00159 &mtprng
00160 };
00161
00162
00163 #define RANDOMGENERATORS (sizeof(randomGeneratorList) / sizeof(randomGenerator*))
00164
00165 int randomGeneratorCount()
00166 {
00167 return RANDOMGENERATORS;
00168 }
00169
00170 const randomGenerator* randomGeneratorGet(int index)
00171 {
00172 if ((index < 0) || (index >= RANDOMGENERATORS))
00173 return (const randomGenerator*) 0;
00174
00175
00176
00177 return randomGeneratorList[index];
00178
00179
00180 }
00181
00182
00183 const randomGenerator* randomGeneratorFind(const char* name)
00184 {
00185 register int index;
00186
00187 for (index = 0; index < RANDOMGENERATORS; index++)
00188 {
00189 if (strcmp(name, randomGeneratorList[index]->name) == 0)
00190
00191 return randomGeneratorList[index];
00192
00193 }
00194 return (const randomGenerator*) 0;
00195 }
00196
00197
00198 const randomGenerator* randomGeneratorDefault()
00199 {
00200 char* selection = getenv("BEECRYPT_RANDOM");
00201
00202 if (selection)
00203 return randomGeneratorFind(selection);
00204 else
00205
00206 return &fips186prng;
00207
00208 }
00209
00210 int randomGeneratorContextInit(randomGeneratorContext* ctxt, const randomGenerator* rng)
00211 {
00212 if (ctxt == (randomGeneratorContext*) 0)
00213 return -1;
00214
00215 if (rng == (randomGenerator*) 0)
00216 return -1;
00217
00218 ctxt->rng = rng;
00219 if (ctxt->param)
00220 free(ctxt->param);
00221 ctxt->param = (randomGeneratorParam*) calloc(rng->paramsize, 1);
00222
00223
00224 if (ctxt->param == (randomGeneratorParam*) 0)
00225 return -1;
00226
00227 return ctxt->rng->setup(ctxt->param);
00228
00229 }
00230
00231 int randomGeneratorContextFree(randomGeneratorContext* ctxt)
00232 {
00233 register int rc;
00234
00235
00236 if (ctxt == (randomGeneratorContext*) 0)
00237 return -1;
00238
00239 if (ctxt->rng == (randomGenerator*) 0)
00240 return -1;
00241
00242 if (ctxt->param == (randomGeneratorParam*) 0)
00243 return -1;
00244
00245
00246 rc = ctxt->rng->cleanup(ctxt->param);
00247
00248 free(ctxt->param);
00249
00250 ctxt->param = (randomGeneratorParam*) 0;
00251
00252
00253 return rc;
00254
00255 }
00256
00257 int randomGeneratorContextNext(randomGeneratorContext* ctxt, uint32* data, int size)
00258 {
00259 return ctxt->rng->next(ctxt->param, data, size);
00260 }
00261
00262
00263
00264 static const hashFunction* hashFunctionList[] =
00265 {
00266 &md5,
00267 &sha1,
00268 &sha256
00269 };
00270
00271
00272 #define HASHFUNCTIONS (sizeof(hashFunctionList) / sizeof(hashFunction*))
00273
00274 int hashFunctionCount()
00275 {
00276 return HASHFUNCTIONS;
00277 }
00278
00279 const hashFunction* hashFunctionDefault()
00280 {
00281 char* selection = getenv("BEECRYPT_HASH");
00282
00283 if (selection)
00284 return hashFunctionFind(selection);
00285 else
00286
00287 return &sha1;
00288
00289 }
00290
00291 const hashFunction* hashFunctionGet(int index)
00292 {
00293 if ((index < 0) || (index >= HASHFUNCTIONS))
00294 return (const hashFunction*) 0;
00295
00296
00297
00298 return hashFunctionList[index];
00299
00300
00301 }
00302
00303
00304 const hashFunction* hashFunctionFind(const char* name)
00305 {
00306 register int index;
00307
00308 for (index = 0; index < HASHFUNCTIONS; index++)
00309 {
00310 if (strcmp(name, hashFunctionList[index]->name) == 0)
00311
00312 return hashFunctionList[index];
00313
00314 }
00315 return (const hashFunction*) 0;
00316 }
00317
00318
00319 int hashFunctionContextInit(hashFunctionContext* ctxt, const hashFunction* hash)
00320 {
00321 if (ctxt == (hashFunctionContext*) 0)
00322 return -1;
00323
00324 if (hash == (hashFunction*) 0)
00325 return -1;
00326
00327 ctxt->algo = hash;
00328 if (ctxt->param)
00329 free(ctxt->param);
00330 ctxt->param = (hashFunctionParam*) calloc(hash->paramsize, 1);
00331
00332
00333 if (ctxt->param == (hashFunctionParam*) 0)
00334 return -1;
00335
00336 return ctxt->algo->reset(ctxt->param);
00337
00338 }
00339
00340 int hashFunctionContextFree(hashFunctionContext* ctxt)
00341 {
00342
00343 if (ctxt == (hashFunctionContext*) 0)
00344 return -1;
00345
00346 if (ctxt->param == (hashFunctionParam*) 0)
00347 return -1;
00348
00349
00350 free(ctxt->param);
00351
00352 ctxt->param = (hashFunctionParam*) 0;
00353
00354
00355 return 0;
00356
00357 }
00358
00359 int hashFunctionContextReset(hashFunctionContext* ctxt)
00360 {
00361 if (ctxt == (hashFunctionContext*) 0)
00362 return -1;
00363
00364 if (ctxt->algo == (hashFunction*) 0)
00365 return -1;
00366
00367 if (ctxt->param == (hashFunctionParam*) 0)
00368 return -1;
00369
00370 return ctxt->algo->reset(ctxt->param);
00371 }
00372
00373 int hashFunctionContextUpdate(hashFunctionContext* ctxt, const byte* data, int size)
00374 {
00375 if (ctxt == (hashFunctionContext*) 0)
00376 return -1;
00377
00378 if (ctxt->algo == (hashFunction*) 0)
00379 return -1;
00380
00381 if (ctxt->param == (hashFunctionParam*) 0)
00382 return -1;
00383
00384 if (data == (const byte*) 0)
00385 return -1;
00386
00387 return ctxt->algo->update(ctxt->param, data, size);
00388 }
00389
00390 int hashFunctionContextUpdateMC(hashFunctionContext* ctxt, const memchunk* m)
00391 {
00392 if (ctxt == (hashFunctionContext*) 0)
00393 return -1;
00394
00395 if (ctxt->algo == (hashFunction*) 0)
00396 return -1;
00397
00398 if (ctxt->param == (hashFunctionParam*) 0)
00399 return -1;
00400
00401 if (m == (memchunk*) 0)
00402 return -1;
00403
00404 return ctxt->algo->update(ctxt->param, m->data, m->size);
00405 }
00406
00407
00408 int hashFunctionContextUpdateMP32(hashFunctionContext* ctxt, const mp32number* n)
00409 {
00410 if (ctxt == (hashFunctionContext*) 0)
00411 return -1;
00412
00413 if (ctxt->algo == (hashFunction*) 0)
00414 return -1;
00415
00416 if (ctxt->param == (hashFunctionParam*) 0)
00417 return -1;
00418
00419 if (n != (mp32number*) 0)
00420 {
00421 register int rc = -1;
00422 register byte* temp = (byte*) malloc((n->size << 2) + 1);
00423
00424
00425 if (mp32msbset(n->size, n->data))
00426 {
00427 temp[0] = 0;
00428 (void) encodeInts((javaint*) n->data, temp+1, n->size);
00429 rc = ctxt->algo->update(ctxt->param, temp, (n->size << 2) + 1);
00430 }
00431 else
00432 {
00433 (void) encodeInts((javaint*) n->data, temp, n->size);
00434 rc = ctxt->algo->update(ctxt->param, temp, n->size << 2);
00435 }
00436 free(temp);
00437
00438
00439 return rc;
00440 }
00441 return -1;
00442 }
00443
00444
00445 int hashFunctionContextDigest(hashFunctionContext* ctxt, mp32number* dig)
00446 {
00447 if (ctxt == (hashFunctionContext*) 0)
00448 return -1;
00449
00450 if (ctxt->algo == (hashFunction*) 0)
00451 return -1;
00452
00453 if (ctxt->param == (hashFunctionParam*) 0)
00454 return -1;
00455
00456 if (dig != (mp32number*) 0)
00457 {
00458 mp32nsize(dig, (ctxt->algo->digestsize + 3) >> 2);
00459
00460 return ctxt->algo->digest(ctxt->param, dig->data);
00461 }
00462 return -1;
00463 }
00464
00465 int hashFunctionContextDigestMatch(hashFunctionContext* ctxt, const mp32number* match)
00466 {
00467 register int rc = 0;
00468
00469 mp32number dig;
00470
00471 mp32nzero(&dig);
00472
00473 if (hashFunctionContextDigest(ctxt, &dig) == 0)
00474 if (dig.size == match->size)
00475 rc = mp32eq(dig.size, dig.data, match->data);
00476
00477 mp32nfree(&dig);
00478
00479
00480 return rc;
00481
00482 }
00483
00484
00485
00486 static const keyedHashFunction* keyedHashFunctionList[] =
00487 {
00488 &hmacmd5,
00489 &hmacsha1,
00490 &hmacsha256
00491 };
00492
00493
00494 #define KEYEDHASHFUNCTIONS (sizeof(keyedHashFunctionList) / sizeof(keyedHashFunction*))
00495
00496 int keyedHashFunctionCount()
00497 {
00498 return KEYEDHASHFUNCTIONS;
00499 }
00500
00501 const keyedHashFunction* keyedHashFunctionDefault()
00502 {
00503 char* selection = getenv("BEECRYPT_KEYEDHASH");
00504
00505 if (selection)
00506 return keyedHashFunctionFind(selection);
00507 else
00508
00509 return &hmacsha1;
00510
00511 }
00512
00513 const keyedHashFunction* keyedHashFunctionGet(int index)
00514 {
00515 if ((index < 0) || (index >= KEYEDHASHFUNCTIONS))
00516 return (const keyedHashFunction*) 0;
00517
00518
00519
00520 return keyedHashFunctionList[index];
00521
00522
00523 }
00524
00525
00526 const keyedHashFunction* keyedHashFunctionFind(const char* name)
00527 {
00528 register int index;
00529
00530 for (index = 0; index < KEYEDHASHFUNCTIONS; index++)
00531 {
00532 if (strcmp(name, keyedHashFunctionList[index]->name) == 0)
00533
00534 return keyedHashFunctionList[index];
00535
00536 }
00537 return (const keyedHashFunction*) 0;
00538 }
00539
00540
00541 int keyedHashFunctionContextInit(keyedHashFunctionContext* ctxt, const keyedHashFunction* mac)
00542 {
00543 if (ctxt == (keyedHashFunctionContext*) 0)
00544 return -1;
00545
00546 if (mac == (keyedHashFunction*) 0)
00547 return -1;
00548
00549 ctxt->algo = mac;
00550 if (ctxt->param)
00551 free(ctxt->param);
00552 ctxt->param = (keyedHashFunctionParam*) calloc(mac->paramsize, 1);
00553
00554
00555 if (ctxt->param == (keyedHashFunctionParam*) 0)
00556 return -1;
00557
00558 return ctxt->algo->reset(ctxt->param);
00559
00560 }
00561
00562 int keyedHashFunctionContextFree(keyedHashFunctionContext* ctxt)
00563 {
00564
00565 if (ctxt == (keyedHashFunctionContext*) 0)
00566 return -1;
00567
00568 if (ctxt->algo == (keyedHashFunction*) 0)
00569 return -1;
00570
00571 if (ctxt->param == (keyedHashFunctionParam*) 0)
00572 return -1;
00573
00574
00575 free(ctxt->param);
00576
00577 ctxt->param = (keyedHashFunctionParam*) 0;
00578
00579
00580 return 0;
00581
00582 }
00583
00584 int keyedHashFunctionContextSetup(keyedHashFunctionContext* ctxt, const uint32* key, int keybits)
00585 {
00586 if (ctxt == (keyedHashFunctionContext*) 0)
00587 return -1;
00588
00589 if (ctxt->algo == (keyedHashFunction*) 0)
00590 return -1;
00591
00592 if (ctxt->param == (keyedHashFunctionParam*) 0)
00593 return -1;
00594
00595 if (key == (uint32*) 0)
00596 return -1;
00597
00598 return ctxt->algo->setup(ctxt->param, key, keybits);
00599 }
00600
00601 int keyedHashFunctionContextReset(keyedHashFunctionContext* ctxt)
00602 {
00603 if (ctxt == (keyedHashFunctionContext*) 0)
00604 return -1;
00605
00606 if (ctxt->algo == (keyedHashFunction*) 0)
00607 return -1;
00608
00609 if (ctxt->param == (keyedHashFunctionParam*) 0)
00610 return -1;
00611
00612 return ctxt->algo->reset(ctxt->param);
00613 }
00614
00615 int keyedHashFunctionContextUpdate(keyedHashFunctionContext* ctxt, const byte* data, int size)
00616 {
00617 if (ctxt == (keyedHashFunctionContext*) 0)
00618 return -1;
00619
00620 if (ctxt->algo == (keyedHashFunction*) 0)
00621 return -1;
00622
00623 if (ctxt->param == (keyedHashFunctionParam*) 0)
00624 return -1;
00625
00626 if (data == (byte*) 0)
00627 return -1;
00628
00629 return ctxt->algo->update(ctxt->param, data, size);
00630 }
00631
00632 int keyedHashFunctionContextUpdateMC(keyedHashFunctionContext* ctxt, const memchunk* m)
00633 {
00634 if (ctxt == (keyedHashFunctionContext*) 0)
00635 return -1;
00636
00637 if (ctxt->algo == (keyedHashFunction*) 0)
00638 return -1;
00639
00640 if (ctxt->param == (keyedHashFunctionParam*) 0)
00641 return -1;
00642
00643 if (m == (memchunk*) 0)
00644 return -1;
00645
00646 return ctxt->algo->update(ctxt->param, m->data, m->size);
00647 }
00648
00649
00650 int keyedHashFunctionContextUpdateMP32(keyedHashFunctionContext* ctxt, const mp32number* n)
00651 {
00652 if (ctxt == (keyedHashFunctionContext*) 0)
00653 return -1;
00654
00655 if (ctxt->algo == (keyedHashFunction*) 0)
00656 return -1;
00657
00658 if (ctxt->param == (keyedHashFunctionParam*) 0)
00659 return -1;
00660
00661 if (n != (mp32number*) 0)
00662 {
00663 register int rc;
00664 register byte* temp = (byte*) malloc((n->size << 2) + 1);
00665
00666
00667 if (mp32msbset(n->size, n->data))
00668 {
00669 temp[0] = 0;
00670 (void) encodeInts((javaint*) n->data, temp+1, n->size);
00671 rc = ctxt->algo->update(ctxt->param, temp, (n->size << 2) + 1);
00672 }
00673 else
00674 {
00675 (void) encodeInts((javaint*) n->data, temp, n->size);
00676 rc = ctxt->algo->update(ctxt->param, temp, n->size << 2);
00677 }
00678 free(temp);
00679
00680
00681 return rc;
00682 }
00683 return -1;
00684 }
00685
00686
00687 int keyedHashFunctionContextDigest(keyedHashFunctionContext* ctxt, mp32number* dig)
00688 {
00689 if (ctxt == (keyedHashFunctionContext*) 0)
00690 return -1;
00691
00692 if (ctxt->algo == (keyedHashFunction*) 0)
00693 return -1;
00694
00695 if (ctxt->param == (keyedHashFunctionParam*) 0)
00696 return -1;
00697
00698 if (dig != (mp32number*) 0)
00699 {
00700 mp32nsize(dig, (ctxt->algo->digestsize + 3) >> 2);
00701
00702 return ctxt->algo->digest(ctxt->param, dig->data);
00703 }
00704 return -1;
00705 }
00706
00707 int keyedHashFunctionContextDigestMatch(keyedHashFunctionContext* ctxt, const mp32number* match)
00708 {
00709 register int rc = 0;
00710
00711 mp32number dig;
00712
00713 mp32nzero(&dig);
00714
00715 if (keyedHashFunctionContextDigest(ctxt, &dig) == 0)
00716 if (dig.size == match->size)
00717
00718 rc = mp32eq(dig.size, dig.data, match->data);
00719
00720 mp32nfree(&dig);
00721
00722
00723 return rc;
00724
00725 }
00726
00727
00728
00729
00730 static const blockCipher* blockCipherList[] =
00731 {
00732 &aes,
00733 &blowfish
00734 };
00735
00736
00737 #define BLOCKCIPHERS (sizeof(blockCipherList) / sizeof(blockCipher*))
00738
00739 int blockCipherCount()
00740 {
00741 return BLOCKCIPHERS;
00742 }
00743
00744 const blockCipher* blockCipherDefault()
00745 {
00746 char* selection = getenv("BEECRYPT_CIPHER");
00747
00748 if (selection)
00749 return blockCipherFind(selection);
00750 else
00751
00752 return &blowfish;
00753
00754 }
00755
00756 const blockCipher* blockCipherGet(int index)
00757 {
00758 if ((index < 0) || (index >= BLOCKCIPHERS))
00759 return (const blockCipher*) 0;
00760
00761
00762
00763 return blockCipherList[index];
00764
00765
00766 }
00767
00768
00769 const blockCipher* blockCipherFind(const char* name)
00770 {
00771 register int index;
00772
00773 for (index = 0; index < BLOCKCIPHERS; index++)
00774 {
00775 if (strcmp(name, blockCipherList[index]->name) == 0)
00776
00777 return blockCipherList[index];
00778
00779 }
00780
00781 return (const blockCipher*) 0;
00782 }
00783
00784
00785 int blockCipherContextInit(blockCipherContext* ctxt, const blockCipher* ciph)
00786 {
00787 if (ctxt == (blockCipherContext*) 0)
00788 return -1;
00789
00790 if (ciph == (blockCipher*) 0)
00791 return -1;
00792
00793 ctxt->algo = ciph;
00794 if (ctxt->param)
00795 free(ctxt->param);
00796 ctxt->param = (blockCipherParam*) calloc(ciph->paramsize, 1);
00797
00798
00799 if (ctxt->param == (blockCipherParam*) 0)
00800 return -1;
00801
00802 return 0;
00803
00804 }
00805
00806 int blockCipherContextSetup(blockCipherContext* ctxt, const uint32* key, int keybits, cipherOperation op)
00807 {
00808 if (ctxt == (blockCipherContext*) 0)
00809 return -1;
00810
00811 if (ctxt->algo == (blockCipher*) 0)
00812 return -1;
00813
00814 if (ctxt->param == (blockCipherParam*) 0)
00815 return -1;
00816
00817 if (key == (uint32*) 0)
00818 return -1;
00819
00820 return ctxt->algo->setup(ctxt->param, key, keybits, op);
00821 }
00822
00823 int blockCipherContextSetIV(blockCipherContext* ctxt, const uint32* iv)
00824 {
00825 if (ctxt == (blockCipherContext*) 0)
00826 return -1;
00827
00828 if (ctxt->algo == (blockCipher*) 0)
00829 return -1;
00830
00831 if (ctxt->param == (blockCipherParam*) 0)
00832 return -1;
00833
00834
00835
00836 return ctxt->algo->setiv(ctxt->param, iv);
00837 }
00838
00839 int blockCipherContextFree(blockCipherContext* ctxt)
00840 {
00841
00842 if (ctxt == (blockCipherContext*) 0)
00843 return -1;
00844
00845 if (ctxt->param == (blockCipherParam*) 0)
00846 return -1;
00847
00848
00849 free(ctxt->param);
00850
00851 ctxt->param = (blockCipherParam*) 0;
00852
00853
00854 return 0;
00855
00856 }
00857
00858 #if WIN32
00859 __declspec(dllexport)
00860 BOOL WINAPI DllMain(HINSTANCE hInst, DWORD wDataSeg, LPVOID lpReserved)
00861 {
00862 switch (wDataSeg)
00863 {
00864 case DLL_PROCESS_ATTACH:
00865 entropy_provider_setup(hInst);
00866 break;
00867 case DLL_PROCESS_DETACH:
00868 entropy_provider_cleanup();
00869 break;
00870 }
00871 return TRUE;
00872 }
00873 #endif
00874