--- ./liboath/usersfile.c 2016-08-27 06:15:06.000000000 -0500 +++ ./liboath/usersfile.c 2018-05-14 03:43:41.244789566 -0500 @@ -79,6 +79,7 @@ parse_usersfile (const char *username, const char *otp, size_t window, + size_t hmacsha, const char *passwd, time_t * last_otp, FILE * infh, @@ -193,9 +194,9 @@ else if (prev_otp) { int prev_otp_pos, this_otp_pos, tmprc; - rc = oath_totp_validate2 (secret, secret_length, + rc = oath_totp_validate4 (secret, secret_length, time (NULL), totpstepsize, 0, window, - &this_otp_pos, otp); + &this_otp_pos, NULL, hmacsha, otp); if (rc == OATH_INVALID_OTP) { (*skipped_users)++; @@ -203,15 +204,15 @@ } if (rc < 0) return rc; - tmprc = oath_totp_validate2 (secret, secret_length, + tmprc = oath_totp_validate4 (secret, secret_length, time (NULL), totpstepsize, 0, window, - &prev_otp_pos, prev_otp); + &prev_otp_pos, NULL, hmacsha, prev_otp); if (tmprc >= 0 && prev_otp_pos >= this_otp_pos) return OATH_REPLAYED_OTP; } else - rc = oath_totp_validate (secret, secret_length, - time (NULL), totpstepsize, 0, window, otp); + rc = oath_totp_validate4 (secret, secret_length, + time (NULL), totpstepsize, 0, window, NULL, NULL, hmacsha, otp); if (rc == OATH_INVALID_OTP) { (*skipped_users)++; @@ -444,6 +445,7 @@ const char *username, const char *otp, size_t window, + size_t hmacsha, const char *passwd, time_t * last_otp) { FILE *infh; @@ -457,7 +459,7 @@ if (!infh) return OATH_NO_SUCH_FILE; - rc = parse_usersfile (username, otp, window, passwd, last_otp, + rc = parse_usersfile (username, otp, window, hmacsha, passwd, last_otp, infh, &line, &n, &new_moving_factor, &skipped_users); if (rc == OATH_OK) --- ./liboath/oath.h 2016-08-27 06:19:49.000000000 -0500 +++ ./liboath/oath.h 2018-05-11 08:57:24.178122669 -0500 @@ -356,6 +356,7 @@ const char *username, const char *otp, size_t window, + size_t hmacsha, const char *passwd, time_t * last_otp); --- ./liboath/hotp.c 2016-08-27 06:15:06.000000000 -0500 +++ ./liboath/hotp.c 2018-05-11 05:34:07.834067421 -0500 @@ -97,13 +97,13 @@ counter[i] = (moving_factor >> ((sizeof (moving_factor) - i - 1) * 8)) & 0xFF; - if (flags & OATH_TOTP_HMAC_SHA256) + if (flags == 1) { hssize = GC_SHA256_DIGEST_SIZE; rc = gc_hmac_sha256 (secret, secret_length, counter, sizeof (moving_factor), hs); } - else if (flags & OATH_TOTP_HMAC_SHA512) + else if (flags == 2) { hssize = GC_SHA512_DIGEST_SIZE; rc = gc_hmac_sha512 (secret, secret_length, --- ./pam_oath/pam_oath.c 2016-08-27 06:15:06.000000000 -0500 +++ ./pam_oath/pam_oath.c 2018-05-11 02:55:27.146837215 -0500 @@ -72,6 +72,7 @@ char *usersfile; unsigned digits; unsigned window; + unsigned hmacsha; }; static void @@ -86,6 +87,7 @@ cfg->usersfile = NULL; cfg->digits = -1; cfg->window = 5; + cfg->hmacsha = 0; for (i = 0; i < argc; i++) { @@ -103,6 +105,8 @@ cfg->digits = atoi (argv[i] + 7); if (strncmp (argv[i], "window=", 7) == 0) cfg->window = atoi (argv[i] + 7); + if (strncmp (argv[i], "hmacsha=", 8) == 0) + cfg->hmacsha = atoi (argv[i] + 8); } if (cfg->digits != 6 && cfg->digits != 7 && cfg->digits != 8) @@ -113,6 +117,13 @@ cfg->digits = 0; } + if (cfg->hmacsha != 0 && cfg->hmacsha != 1 && cfg->hmacsha != 2) + { + D (("only 0, 1, and 2 hmac SHA values are supported: invalid value %d", + cfg->hmacsha)); + cfg->hmacsha = 0; + } + if (cfg->debug) { D (("called.")); @@ -126,6 +137,7 @@ D (("usersfile=%s", cfg->usersfile ? cfg->usersfile : "(null)")); D (("digits=%d", cfg->digits)); D (("window=%d", cfg->window)); + D (("hmacsha=%d", cfg->hmacsha)); } } @@ -306,7 +318,7 @@ rc = oath_authenticate_usersfile (cfg.usersfile, user, - otp, cfg.window, onlypasswd, &last_otp); + otp, cfg.window, cfg.hmacsha, onlypasswd, &last_otp); DBG (("authenticate rc %d (%s: %s) last otp %s", rc, oath_strerror_name (rc) ? oath_strerror_name (rc) : "UNKNOWN", oath_strerror (rc), ctime (&last_otp)));