RFC Errata
RFC 6287, "OCRA: OATH Challenge-Response Algorithm", June 2011
Source of RFC: IETF - NON WORKING GROUPArea Assignment: sec
Errata ID: 5625
Status: Reported
Type: Technical
Publication Format(s) : TEXT
Reported By: Emanuele Giacomelli
Date Reported: 2019-02-07
Section Appendix A says:
// put selected bytes into result int int offset = hash[hash.length - 1] & 0xf; int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); int otp = binary % DIGITS_POWER[codeDigits]; result = Integer.toString(otp); while (result.length() < codeDigits) { result = "0" + result; } return result;
It should say:
if (codeDigits > 0) { // put selected bytes into result int int offset = hash[hash.length - 1] & 0xf; int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); int otp = binary % DIGITS_POWER[codeDigits]; result = Integer.toString(otp); while (result.length() < codeDigits) { result = "0" + result; } return result; } else { return asHex(hash); }
Notes:
The code does not honor what the RFC says in section 5.2:
3. t=0 means that no truncation is performed and the full HMAC value
is used for authentication purposes
and still applies dynamic truncation to suites requesting "0" digits.
As a result, the computation performs a "modulo 1" operation causing
the code to always return 0 for such suites.
The proposed patch explicitly disables dynamic truncation for such suites and returns the full HMAC
encoded as a Base16 string. The "asHex" function is the same defined in Appendix B.