RFC Errata
RFC 4226, "HOTP: An HMAC-Based One-Time Password Algorithm", December 2005
Source of RFC: IETF - NON WORKING GROUPArea Assignment: sec
See Also: RFC 4226 w/ inline errata
Errata ID: 5130
Status: Verified
Type: Technical
Publication Format(s) : TEXT
Reported By: Gerrit Jansen van Vuuren
Date Reported: 2017-09-27
Verifier Name: Paul Wouters
Date Verified: 2023-08-03
Section Appendix C says:
static public String generateOTP(byte[] secret, long movingFactor, int codeDigits, boolean addChecksum, int truncationOffset) throws NoSuchAlgorithmException, InvalidKeyException { // put movingFactor value into text byte array String result = null; int digits = addChecksum ? (codeDigits + 1) : codeDigits; byte[] text = new byte[8]; for (int i = text.length - 1; i >= 0; i--) { text[i] = (byte) (movingFactor & 0xff); movingFactor >>= 8; }
It should say:
static public String generateOTP(byte[] secret, long movingFactor, int codeDigits, boolean addChecksum, int truncationOffset) throws NoSuchAlgorithmException, InvalidKeyException { // put movingFactor value into text byte array String result = null; long count = movingFactor; int digits = addChecksum ? (codeDigits + 1) : codeDigits; byte[] text = new byte[8]; for (int i = text.length - 1; i >= 0; i--) { text[i] = (byte) (count & 0xff); count >>= 8; }
Notes:
method parameters like movingFactor should not be edited or changed in the method logic. This may lead to misunderstanding and bugs when the code is ported to other platforms and or re-implemented. Here movingFactor would be expected to stay constant and can be reused, but the original implementation updates the value to 0, which means any extra logic or updates (even debug statements) would always see movingFactor == 0 no matter what.