Main Page Modules Data Structures File List Data Fields Globals Related Pages

# beecrypt/beecrypt.c

Go to the documentation of this file.

    00001 /*@-sizeoftype@*/
    00008 /*
    00009  * Copyright (c) 1999, 2000, 2001, 2002 Virtual Unlimited B.V.
    00010  *
    00011  * Author: Bob Deblier <bob@virtualunlimited.com>
    00012  *
    00013  * This library is free software; you can redistribute it and/or
    00014  * modify it under the terms of the GNU Lesser General Public
    00015  * License as published by the Free Software Foundation; either
    00016  * version 2.1 of the License, or (at your option) any later version.
    00017  *
    00018  * This library is distributed in the hope that it will be useful,
    00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00021  * Lesser General Public License for more details.
    00022  *
    00023  * You should have received a copy of the GNU Lesser General Public
    00024  * License along with this library; if not, write to the Free Software
    00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00026  *
    00027  */
    00028
    00029 #include "system.h"
    00030 #include "beecrypt.h"
    00031
    00032 #if defined(__LCLINT__)
    00033 /* XXX from /usr/include/bits/sigest.h in glibc-2.2.4 */
    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 /*@-type@*/ /* FIX: cast? */
    00060 /*@observer@*/ /*@unchecked@*/
    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 /*@=type@*/
    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 /*@-boundsread@*/
    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 /*@=boundsread@*/
    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 /*@-boundsread@*/
    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 /*@=boundsread@*/
    00153
    00154 /*@-type@*/ /* FIX: cast? */
    00155 /*@observer@*/ /*@unchecked@*/
    00156 static const randomGenerator* randomGeneratorList[] =
    00157 {
    00158         &fips186prng,
    00159         &mtprng
    00160 };
    00161 /*@=type@*/
    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 /*@-boundsread@*/
    00176         /*@-compmempass@*/
    00177         return randomGeneratorList[index];
    00178         /*@=compmempass@*/
    00179 /*@=boundsread@*/
    00180 }
    00181
    00182 /*@-boundsread@*/
    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                         /*@-compmempass@*/
    00191                         return randomGeneratorList[index];
    00192                         /*@=compmempass@*/
    00193         }
    00194         return (const randomGenerator*) 0;
    00195 }
    00196 /*@=boundsread@*/
    00197
    00198 const randomGenerator* randomGeneratorDefault()
    00199 {
    00200         char* selection = getenv("BEECRYPT_RANDOM");
    00201
    00202         if (selection)
    00203                 return randomGeneratorFind(selection);
    00204         else
    00205                 /*@-globs -compmempass @*/
    00206                 return &fips186prng;
    00207                 /*@=globs =compmempass @*/
    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)        /* XXX error? */
    00220                 free(ctxt->param);
    00221         ctxt->param = (randomGeneratorParam*) calloc(rng->paramsize, 1);
    00222
    00223         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00224         if (ctxt->param == (randomGeneratorParam*) 0)
    00225                 return -1;
    00226
    00227         return ctxt->rng->setup(ctxt->param);
    00228         /*@=nullstate@*/
    00229 }
    00230
    00231 int randomGeneratorContextFree(randomGeneratorContext* ctxt)
    00232 {
    00233         register int rc;
    00234
    00235         /*@-mustfree@*/
    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         /*@=mustfree@*/
    00245
    00246         rc = ctxt->rng->cleanup(ctxt->param);
    00247
    00248         free(ctxt->param);
    00249
    00250         ctxt->param = (randomGeneratorParam*) 0;
    00251
    00252         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00253         return rc;
    00254         /*@=nullstate@*/
    00255 }
    00256
    00257 int randomGeneratorContextNext(randomGeneratorContext* ctxt, uint32* data, int size)
    00258 {
    00259         return ctxt->rng->next(ctxt->param, data, size);
    00260 }
    00261
    00262 /*@-type@*/ /* FIX: cast? */
    00263 /*@observer@*/ /*@unchecked@*/
    00264 static const hashFunction* hashFunctionList[] =
    00265 {
    00266         &md5,
    00267         &sha1,
    00268         &sha256
    00269 };
    00270 /*@=type@*/
    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                 /*@-globs -compmempass @*/
    00287                 return &sha1;
    00288                 /*@=globs =compmempass @*/
    00289 }
    00290
    00291 const hashFunction* hashFunctionGet(int index)
    00292 {
    00293         if ((index < 0) || (index >= HASHFUNCTIONS))
    00294                 return (const hashFunction*) 0;
    00295
    00296 /*@-boundsread@*/
    00297         /*@-compmempass@*/
    00298         return hashFunctionList[index];
    00299         /*@=compmempass@*/
    00300 /*@=boundsread@*/
    00301 }
    00302
    00303 /*@-boundsread@*/
    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                         /*@-compmempass@*/
    00312                         return hashFunctionList[index];
    00313                         /*@=compmempass@*/
    00314         }
    00315         return (const hashFunction*) 0;
    00316 }
    00317 /*@=boundsread@*/
    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)        /* XXX error? */
    00329                 free(ctxt->param);
    00330         ctxt->param = (hashFunctionParam*) calloc(hash->paramsize, 1);
    00331
    00332         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00333         if (ctxt->param == (hashFunctionParam*) 0)
    00334                 return -1;
    00335
    00336         return ctxt->algo->reset(ctxt->param);
    00337         /*@=nullstate@*/
    00338 }
    00339
    00340 int hashFunctionContextFree(hashFunctionContext* ctxt)
    00341 {
    00342         /*@-mustfree@*/
    00343         if (ctxt == (hashFunctionContext*) 0)
    00344                 return -1;
    00345
    00346         if (ctxt->param == (hashFunctionParam*) 0)
    00347                 return -1;
    00348         /*@=mustfree@*/
    00349
    00350         free(ctxt->param);
    00351
    00352         ctxt->param = (hashFunctionParam*) 0;
    00353
    00354         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00355         return 0;
    00356         /*@=nullstate@*/
    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 /*@-boundswrite@*/
    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                 /*@-nullpass -nullderef -nullptrarith @*/ /* FIX: temp may be NULL */
    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                 /*@=nullpass =nullderef =nullptrarith @*/
    00438
    00439                 return rc;
    00440         }
    00441         return -1;
    00442 }
    00443 /*@=boundswrite@*/
    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         /*@-mustfree@*/ /* dig.data is OK */
    00480         return rc;
    00481         /*@=mustfree@*/
    00482 }
    00483
    00484 /*@-type@*/ /* FIX: cast? */
    00485 /*@observer@*/ /*@unchecked@*/
    00486 static const keyedHashFunction* keyedHashFunctionList[] =
    00487 {
    00488         &hmacmd5,
    00489         &hmacsha1,
    00490         &hmacsha256
    00491 };
    00492 /*@=type@*/
    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                 /*@-globs -compmempass @*/
    00509                 return &hmacsha1;
    00510                 /*@=globs =compmempass @*/
    00511 }
    00512
    00513 const keyedHashFunction* keyedHashFunctionGet(int index)
    00514 {
    00515         if ((index < 0) || (index >= KEYEDHASHFUNCTIONS))
    00516                 return (const keyedHashFunction*) 0;
    00517
    00518 /*@-boundsread@*/
    00519         /*@-compmempass@*/
    00520         return keyedHashFunctionList[index];
    00521         /*@=compmempass@*/
    00522 /*@=boundsread@*/
    00523 }
    00524
    00525 /*@-boundsread@*/
    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                         /*@-compmempass@*/
    00534                         return keyedHashFunctionList[index];
    00535                         /*@=compmempass@*/
    00536         }
    00537         return (const keyedHashFunction*) 0;
    00538 }
    00539 /*@=boundsread@*/
    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)        /* XXX error? */
    00551                 free(ctxt->param);
    00552         ctxt->param = (keyedHashFunctionParam*) calloc(mac->paramsize, 1);
    00553
    00554         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00555         if (ctxt->param == (keyedHashFunctionParam*) 0)
    00556                 return -1;
    00557
    00558         return ctxt->algo->reset(ctxt->param);
    00559         /*@=nullstate@*/
    00560 }
    00561
    00562 int keyedHashFunctionContextFree(keyedHashFunctionContext* ctxt)
    00563 {
    00564         /*@-mustfree@*/
    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         /*@=mustfree@*/
    00574
    00575         free(ctxt->param);
    00576
    00577         ctxt->param = (keyedHashFunctionParam*) 0;
    00578
    00579         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00580         return 0;
    00581         /*@=nullstate@*/
    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 /*@-boundswrite@*/
    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                 /*@-nullpass -nullderef -nullptrarith @*/ /* FIX: temp may be NULL */
    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                 /*@=nullpass =nullderef =nullptrarith @*/
    00680
    00681                 return rc;
    00682         }
    00683         return -1;
    00684 }
    00685 /*@=boundswrite@*/
    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         /*@-mustfree@*/ /* dig.data is OK */
    00723         return rc;
    00724         /*@=mustfree@*/
    00725 }
    00726
    00727
    00728 /*@-type@*/ /* FIX: cast? */
    00729 /*@observer@*/ /*@unchecked@*/
    00730 static const blockCipher* blockCipherList[] =
    00731 {
    00732         &aes,
    00733         &blowfish
    00734 };
    00735 /*@=type@*/
    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                 /*@-globs -compmempass @*/
    00752                 return &blowfish;
    00753                 /*@=globs =compmempass @*/
    00754 }
    00755
    00756 const blockCipher* blockCipherGet(int index)
    00757 {
    00758         if ((index < 0) || (index >= BLOCKCIPHERS))
    00759                 return (const blockCipher*) 0;
    00760
    00761 /*@-boundsread@*/
    00762         /*@-compmempass@*/
    00763         return blockCipherList[index];
    00764         /*@=compmempass@*/
    00765 /*@=boundsread@*/
    00766 }
    00767
    00768 /*@-boundsread@*/
    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                         /*@-compmempass@*/
    00777                         return blockCipherList[index];
    00778                         /*@=compmempass@*/
    00779         }
    00780
    00781         return (const blockCipher*) 0;
    00782 }
    00783 /*@=boundsread@*/
    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)        /* XXX error? */
    00795                 free(ctxt->param);
    00796         ctxt->param = (blockCipherParam*) calloc(ciph->paramsize, 1);
    00797
    00798         /*@-nullstate@*/ /* FIX: ctxt->param may be NULL */
    00799         if (ctxt->param == (blockCipherParam*) 0)
    00800                 return -1;
    00801
    00802         return 0;
    00803         /*@=nullstate@*/
    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         /* null is an allowed value for iv, so don't test it */
    00835
    00836         return ctxt->algo->setiv(ctxt->param, iv);
    00837 }
    00838
    00839 int blockCipherContextFree(blockCipherContext* ctxt)
    00840 {
    00841         /*@-mustfree@*/
    00842         if (ctxt == (blockCipherContext*) 0)
    00843                 return -1;
    00844
    00845         if (ctxt->param == (blockCipherParam*) 0)
    00846                 return -1;
    00847         /*@=mustfree@*/
    00848
    00849         free(ctxt->param);
    00850
    00851         ctxt->param = (blockCipherParam*) 0;
    00852
    00853         /*@-nullstate@*/ /* FIX: ctxt->param is NULL */
    00854         return 0;
    00855         /*@=nullstate@*/
    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 /*@=sizeoftype@*/