122347Spst/* hash.c: The opiehash() library function.
222347Spst
329967Sache%%% copyright-cmetz-96
492914SmarkmThis software is Copyright 1996-2001 by Craig Metz, All Rights Reserved.
592914SmarkmThe Inner Net License Version 3 applies to this software.
622347SpstYou should have received a copy of the license with this software. If
722347Spstyou didn't get a copy, you may request one from <license@inner.net>.
822347Spst
922347Spst        History:
1022347Spst
1192914Smarkm	Modified by cmetz for OPIE 2.4. Use struct opie_otpkey for binary arg.
1292914Smarkm	Modified by cmetz for OPIE 2.31. Added SHA support (which may
1329967Sache              not be correct). Backed out previous optimizations as
1429967Sache              they killed thread-safety.
1522347Spst        Created by cmetz for OPIE 2.3 using the old hash.c as a guide.
1659121Skris
1759121Skris$FreeBSD$
1822347Spst*/
1922347Spst
20239169Sdelphij#include <sys/endian.h>
21239169Sdelphij
2222347Spst#include "opie_cfg.h"
2322347Spst#include "opie.h"
2422347Spst
2579711Smarkm#include <sha.h>
2622371Spst#include <md4.h>
2722371Spst#include <md5.h>
2822371Spst
2992914SmarkmVOIDRET opiehash FUNCTION((x, algorithm), struct opie_otpkey *x AND
3092914Smarkmunsigned algorithm)
3122347Spst{
3222347Spst  UINT4 *results = (UINT4 *)x;
3322347Spst
3422347Spst  switch(algorithm) {
3522347Spst    case 3:
3629967Sache      {
3729967Sache      SHA_CTX sha;
3879711Smarkm      UINT4 digest[5];
3979711Smarkm      SHA1_Init(&sha);
4079711Smarkm      SHA1_Update(&sha, (unsigned char *)x, 8);
4179711Smarkm      SHA1_Final((unsigned char *)digest, &sha);
4279711Smarkm      results[0] = digest[0] ^ digest[2] ^ digest[4];
4379711Smarkm      results[1] = digest[1] ^ digest[3];
44239169Sdelphij
45239169Sdelphij      /*
46239169Sdelphij       * RFC2289 mandates that we convert SHA1 digest from big-endian to little
47239169Sdelphij       * see Appendix A.
48239169Sdelphij       */
49239169Sdelphij      results[0] = bswap32(results[0]);
50239169Sdelphij      results[1] = bswap32(results[1]);
5129967Sache      };
5222347Spst      break;
5329967Sache    case 4:
5429967Sache      {
5522371Spst      MD4_CTX mdx;
5629967Sache      UINT4 mdx_tmp[4];
5729967Sache
5822371Spst      MD4Init(&mdx);
5922371Spst      MD4Update(&mdx, (unsigned char *)x, 8);
6022371Spst      MD4Final((unsigned char *)mdx_tmp, &mdx);
6122347Spst      results[0] = mdx_tmp[0] ^ mdx_tmp[2];
6222347Spst      results[1] = mdx_tmp[1] ^ mdx_tmp[3];
6329967Sache      };
6422347Spst      break;
6529967Sache    case 5:
6629967Sache      {
6722371Spst      MD5_CTX mdx;
6829967Sache      UINT4 mdx_tmp[4];
6929967Sache
7022371Spst      MD5Init(&mdx);
7122371Spst      MD5Update(&mdx, (unsigned char *)x, 8);
7222371Spst      MD5Final((unsigned char *)mdx_tmp, &mdx);
7322347Spst      results[0] = mdx_tmp[0] ^ mdx_tmp[2];
7422347Spst      results[1] = mdx_tmp[1] ^ mdx_tmp[3];
7529967Sache      };
7622347Spst      break;
7722347Spst  }
7822347Spst}
79