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

# beecrypt/hmac.c

Go to the documentation of this file.

    00001
    00007 /*
    00008  * Copyright (c) 1999, 2000, 2002 Virtual Unlimited B.V.
    00009  *
    00010  * Author: Bob Deblier <bob@virtualunlimited.com>
    00011  *
    00012  * This library is free software; you can redistribute it and/or
    00013  * modify it under the terms of the GNU Lesser General Public
    00014  * License as published by the Free Software Foundation; either
    00015  * version 2.1 of the License, or (at your option) any later version.
    00016  *
    00017  * This library is distributed in the hope that it will be useful,
    00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00020  * Lesser General Public License for more details.
    00021  *
    00022  * You should have received a copy of the GNU Lesser General Public
    00023  * License along with this library; if not, write to the Free Software
    00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00025  *
    00026  */
    00027
    00028 #include "system.h"
    00029 #include "hmac.h"
    00030 #include "mp32.h"
    00031 #include "endianness.h"
    00032 #include "debug.h"
    00033
    00034 #define HMAC_IPAD       0x36
    00035 #define HMAC_OPAD       0x5c
    00036
    00037 /*@-boundswrite@*/
    00038 int hmacSetup(hmacParam* hp, const hashFunction* hash, hashFunctionParam* param, const uint32* key, int keybits)
    00039 {
    00040         register int i, rc;
    00041         int keywords = (((uint32)keybits + 31) >> 5);   /* rounded up */
    00042         int keybytes = (((uint32)keybits     ) >> 3);
    00043
    00044         /* if the key is too large, hash it first */
    00045         if (keybytes > 64)
    00046         {
    00047                 uint32 keydigest[16];
    00048                 byte* tmp;
    00049
    00050                 /* if the hash digest is too large, this doesn't help */
    00051                 if (hash->digestsize > 64)
    00052                         return -1;
    00053
    00054                 if (hash->reset(param))
    00055                         return -1;
    00056
    00057                 tmp = (byte*) malloc(keybytes);
    00058
    00059                 if (tmp == (byte*) 0)
    00060                         return -1;
    00061
    00062                 /* before we can hash the key, we need to encode it! */
    00063                 (void) encodeIntsPartial(key, tmp, keybytes);
    00064
    00065                 rc = hash->update(param, tmp, keybytes);
    00066                 free(tmp);
    00067
    00068                 if (rc)
    00069                         return -1;
    00070
    00071                 memset(keydigest, 0, sizeof(keydigest));
    00072                 if (hash->digest(param, keydigest))
    00073                         return -1;
    00074
    00075                 keywords = hash->digestsize >> 2;
    00076                 keybytes = hash->digestsize;
    00077
    00078                 (void) encodeInts(keydigest, hp->kxi, keybytes);
    00079                 (void) encodeInts(keydigest, hp->kxo, keybytes);
    00080         }
    00081         else if (keybytes > 0)
    00082         {
    00083                 (void) encodeIntsPartial(key, hp->kxi, keybytes);
    00084                 (void) encodeIntsPartial(key, hp->kxo, keybytes);
    00085         }
    00086         else
    00087                 return -1;
    00088
    00089         for (i = 0; i < keybytes; i++)
    00090         {
    00091                 hp->kxi[i] ^= HMAC_IPAD;
    00092                 hp->kxo[i] ^= HMAC_OPAD;
    00093         }
    00094
    00095         for (i = keybytes; i < 64; i++)
    00096         {
    00097                 hp->kxi[i] = HMAC_IPAD;
    00098                 hp->kxo[i] = HMAC_OPAD;
    00099         }
    00100
    00101         return hmacReset(hp, hash, param);
    00102 }
    00103 /*@=boundswrite@*/
    00104
    00105 int hmacReset(hmacParam* hp, const hashFunction* hash, hashFunctionParam* param)
    00106 {
    00107         if (hash->reset(param))
    00108                 return -1;
    00109
    00110         if (hash->update(param, hp->kxi, 64))
    00111                 return -1;
    00112
    00113         return 0;
    00114 }
    00115
    00116 int hmacUpdate(/*@unused@*/ hmacParam* hp, const hashFunction* hash, hashFunctionParam* param, const byte* data, int size)
    00117 {
    00118         return hash->update(param, data, size);
    00119 }
    00120
    00121 int hmacDigest(hmacParam* hp, const hashFunction* hash, hashFunctionParam* param, uint32* data)
    00122 {
    00123         if (hash->digest(param, data))
    00124                 return -1;
    00125
    00126         if (hash->update(param, hp->kxo, 64))
    00127                 return -1;
    00128
    00129         /* digestsize is in bytes; divide by 4 to get the number of words */
    00130         /*@-compdef@*/ /* FIX: *data undef ??? Code looks bogus ... */
    00131         (void) encodeInts((const javaint*) data, (byte*) data, hash->digestsize >> 2);
    00132         /*@=compdef@*/
    00133
    00134         if (hash->update(param, (const byte*) data, hash->digestsize))
    00135                 return -1;
    00136
    00137         if (hash->digest(param, data))
    00138                 return -1;
    00139
    00140         return 0;
    00141 }