add hotp support
authorfcusack <fcusack>
Sun, 18 Sep 2005 06:38:22 +0000 (06:38 +0000)
committerfcusack <fcusack>
Sun, 18 Sep 2005 06:38:22 +0000 (06:38 +0000)
src/modules/rlm_otp/Makefile.in
src/modules/rlm_otp/otp.h
src/modules/rlm_otp/otp_hotp.c [new file with mode: 0644]

index cd881f8..99608c1 100644 (file)
@@ -22,7 +22,7 @@
 #######################################################################
 TARGET         = @targetname@
 SRCS           = otp_rlm.c otp_util.c otp_radstate.c otp_x99.c otp_state.c
-SRCS          += otp_site.c otp_pwe.c otp_log.c otp_cardops.c
+SRCS          += otp_site.c otp_pwe.c otp_log.c otp_cardops.c otp_hotp.c
 HEADERS        = otp.h otp_rad.h otp_pwe.h otp_cardops.h
 RLM_CFLAGS     = @otp_cflags@ $(OPENSSL_INCLUDE)
 CARDOPS_LTLIBS = $(patsubst %.c,%.lo,$(wildcard cardops/*.c))
index a525cde..7725552 100644 (file)
@@ -169,6 +169,11 @@ extern int otp_pw_valid(const char *, char *, const char *, int,
 extern int otp_x99_mac(const unsigned char *, size_t, unsigned char [8],
                        const unsigned char [OTP_MAX_KEY_LEN]);
 
+/* otp_hotp.c */
+extern int otp_hotp_mac(const unsigned char [8], unsigned char [7],
+                        const unsigned char [OTP_MAX_KEY_LEN], size_t,
+                        const char *);
+
 /* otp_util.c */
 /* Character maps for generic hex and vendor specific decimal modes */
 extern const char otp_hex_conversion[];
diff --git a/src/modules/rlm_otp/otp_hotp.c b/src/modules/rlm_otp/otp_hotp.c
new file mode 100644 (file)
index 0000000..509a234
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * otp_hotp.c
+ * $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2005 TRI-D Systems, Inc.
+ */
+
+#include <openssl/hmac.h>
+
+#include "otp.h"
+
+static const char rcsid[] = "$Id$";
+
+
+/*
+ * This implements HOTP per draft-mraihi-oath-hmac-otp-04.txt, for Digit = 6.
+ *
+ * The HOTP algorithm is:
+ * 1. HS = HMAC-SHA-1(K, C)
+ *    Take the SHA-1 HMAC of the key (K) and counter (C).
+ * 2. S = DT(HS)
+ *    Take the "Dynamic Truncation" of the HMAC.
+ * 3. HOTP = StToNum(S) % 10^Digit
+ *    Take the modulus of S as a bigendian integer.
+ *
+ * Returns 0 on success, -1 on failure.  output is the ASCII HOTP on success.
+ */
+int
+otp_hotp_mac(const unsigned char counter[8], unsigned char output[7],
+             const unsigned char keyblock[OTP_MAX_KEY_LEN], size_t key_len,
+             const char *log_prefix)
+{
+  unsigned char hmac[EVP_MAX_MD_SIZE]; /* >=20 */
+  int hmac_len = 0;
+  uint32_t p;
+
+  /* 1. hmac */
+  if (!HMAC(EVP_sha1(), keyblock, key_len, counter, 8, hmac, &hmac_len) ||
+      hmac_len != 20) {
+    otp_log(OTP_LOG_ERR, "%s: HMAC failed: HMAC", log_prefix);
+    return -1;
+  }
+
+  /* 2. the truncate step is unnecessarily complex */
+  {
+    int offset;
+
+    offset = hmac[19] & 0x0F;
+    /* we can't just cast hmac[offset] because of alignment and endianness */
+    p = (hmac[offset] & 0x7F) << 24 |
+        hmac[offset + 1]      << 16 |
+        hmac[offset + 2]      << 8  |
+        hmac[offset + 3];
+  }
+
+  /* 3. int conversion and modulus (as string) */
+  (void) sprintf(output, "%06lu", p % 1000000L);
+
+  return 0;
+}