1/* hash.c: The opiehash() library function.
2
3%%% copyright-cmetz-96
4This software is Copyright 1996-2001 by Craig Metz, All Rights Reserved.
5The Inner Net License Version 3 applies to this software.
6You should have received a copy of the license with this software. If
7you didn't get a copy, you may request one from <license@inner.net>.
8
9        History:
10
11	Modified by cmetz for OPIE 2.4. Use struct opie_otpkey for binary arg.
12	Modified by cmetz for OPIE 2.31. Added SHA support (which may
13              not be correct). Backed out previous optimizations as
14              they killed thread-safety.
15        Created by cmetz for OPIE 2.3 using the old hash.c as a guide.
16
17$FreeBSD$
18*/
19
20#include <sys/endian.h>
21
22#include "opie_cfg.h"
23#include "opie.h"
24
25#include <sha.h>
26#include <md4.h>
27#include <md5.h>
28
29VOIDRET opiehash FUNCTION((x, algorithm), struct opie_otpkey *x AND
30unsigned algorithm)
31{
32  UINT4 *results = (UINT4 *)x;
33
34  switch(algorithm) {
35    case 3:
36      {
37      SHA_CTX sha;
38      UINT4 digest[5];
39      SHA1_Init(&sha);
40      SHA1_Update(&sha, (unsigned char *)x, 8);
41      SHA1_Final((unsigned char *)digest, &sha);
42      results[0] = digest[0] ^ digest[2] ^ digest[4];
43      results[1] = digest[1] ^ digest[3];
44
45      /*
46       * RFC2289 mandates that we convert SHA1 digest from big-endian to little
47       * see Appendix A.
48       */
49      results[0] = bswap32(results[0]);
50      results[1] = bswap32(results[1]);
51      };
52      break;
53    case 4:
54      {
55      MD4_CTX mdx;
56      UINT4 mdx_tmp[4];
57
58      MD4Init(&mdx);
59      MD4Update(&mdx, (unsigned char *)x, 8);
60      MD4Final((unsigned char *)mdx_tmp, &mdx);
61      results[0] = mdx_tmp[0] ^ mdx_tmp[2];
62      results[1] = mdx_tmp[1] ^ mdx_tmp[3];
63      };
64      break;
65    case 5:
66      {
67      MD5_CTX mdx;
68      UINT4 mdx_tmp[4];
69
70      MD5Init(&mdx);
71      MD5Update(&mdx, (unsigned char *)x, 8);
72      MD5Final((unsigned char *)mdx_tmp, &mdx);
73      results[0] = mdx_tmp[0] ^ mdx_tmp[2];
74      results[1] = mdx_tmp[1] ^ mdx_tmp[3];
75      };
76      break;
77  }
78}
79