One-Time Password (OTP) Pre-Authentication
Extracted elements (26)
Different keys are used for encrypting client and server nonces (Client Key vs. Reply Key) to help mitigate reflection attacks against the challenge-response four-pass protocol.
The Client Key and Reply Key are derived from both the Armor Key and the OTP value using KRB-FX-CF2, achieving cryptographic binding to the outer FAST tunnel. This mitigates man-in-the-middle attacks against the tunneled pre-authentication protocol, as described by [ASNINY02].
The protocol supports OTP algorithms where the KDC cannot obtain the plaintext OTP (e.g., RFC 2289 challenge-response). When must-encrypt-nonce is not set, the OTP value is sent in the otp-value field of the PA-OTP-REQUEST; keys then fall back to the Armor Key, at the cost of losing KDC-authentication via the OTP mechanism itself.
All implementations SHOULD provide a pluggable mechanism (e.g., a provider interface) to add or remove support for particular OTP mechanisms (time-based, counter-based, challenge-response, connected tokens), ensuring interoperability across diverse OTP algorithm types.
Clients SHOULD NOT normalize the PIN value or any OTP value collected from the user or returned by a connected token in any way.
If the collect-pin and do-not-collect-pin flags are both set in an OTP-TOKENINFO, the client SHALL regard the request as invalid; the two flags are mutually exclusive.
If the KDC determines that the user's PIN has expired, it SHOULD respond with KRB-ERROR of type KDC_ERR_PIN_EXPIRED (96) and MAY include a PA-OTP-PIN-CHANGE in the armored-data of the PA-FX-FAST-REPLY.
If the KDC requires that OTP-based pre-authentication is used and no PA-OTP-REQUEST is present in the initial AS-REQ, the KDC SHALL respond with a KRB-ERROR containing a PA-OTP-CHALLENGE inside the enc-fast-rep of a PA-FX-FAST-REPLY encrypted under the Armor Key.
If the must-encrypt-nonce flag is set in the OTP-TOKENINFO, the OTP value MUST be used to generate the Client Key and Reply Key as described in Section 3.6 and MUST NOT be included in the otp-value field of the PA-OTP-REQUEST. If the flag is not set, the OTP value MUST be included in otp-value and MUST NOT be used in key derivation.
Support for SHA-256 by both client and KDC is REQUIRED when hashed OTP values are used. The client MUST select the first algorithm from the supportedHashAlg list in the PA-OTP-CHALLENGE that it supports.
The client MUST NOT use an iteration count lower than that specified by the KDC in the PA-OTP-CHALLENGE; it MAY use a larger value. The chosen value MUST be returned in the iterationCount field of the PA-OTP-REQUEST.
The KDC MUST fail the authentication request with KDC_ERR_INVALID_HASH_ALG (94) if hashed OTP values are required but the hashAlg field is absent or non-conforming; with KDC_ERR_INVALID_ITERATION_COUNT (95) if the iterationCount is below the value specified in PA-OTP-CHALLENGE; and with KDC_ERR_PIN_REQUIRED (97) if a separate PIN is required but otp-pin was not included.
The nonce in PA-OTP-CHALLENGE MUST contain a randomly chosen component at least as long as the Armor Key length, as required by RFC 4086.
Unless the identity of the KDC has been verified, anonymous PKINIT SHALL NOT be used with OTP algorithms that require the OTP value to be sent to the KDC (i.e., where must-encrypt-nonce is not set).
PA-OTP-CHALLENGE (padata-type 141) is returned by the KDC in a KRB-ERROR when OTP pre-authentication is required. It carries a server-generated nonce, optional otp-service string, one or more OTP-TOKENINFO elements describing acceptable tokens, and optional salt and string-to-key parameters.
PA-OTP-PIN-CHANGE (padata-type 144) is returned by the KDC in the enc-fast-rep of a PA-FX-FAST-REPLY to indicate PIN expiry, PIN change, or to convey a system-set PIN. It carries PinFlags (systemSetPin, mandatory), optional pin value, optional minLength/maxLength constraints, optional last-req for expiry times, and optional format restrictions.
PA-OTP-REQUEST (padata-type 142) is sent by the client to the KDC within the KrbFastReq padata of a PA-FX-FAST-REQUEST. It carries OTPFlags, optional client nonce (for hashed OTP), encData encrypted under the Client Key (containing either PA-OTP-ENC-REQUEST or PA-ENC-TS-ENC), optional hash algorithm and iteration count, and optional OTP metadata (value, PIN, challenge, time, counter, format, tokenID, algID, vendor).
Reply Key generation uses the KRB-FX-CF2 algorithm from RFC 6113: Client Key = KRB-FX-CF2(ArmorKey, K2, "OTPComb1", "OTPComb2") and Reply Key = KRB-FX-CF2(ArmorKey, K2, "OTPComb3", "OTPComb4"), where K2 is derived from the OTP value (or its iterated hash) via string-to-key with the label "Krb-preAuth".
This document registers pre-authentication types PA-OTP-CHALLENGE (141), PA-OTP-REQUEST (142), and PA-OTP-PIN-CHANGE (144) in the Kerberos pre-authentication type registry created by RFC 6113. PA-OTP-CONFIRM (143) is marked OBSOLETE. Error codes KDC_ERR_INVALID_HASH_ALG (94), KDC_ERR_INVALID_ITERATION_COUNT (95), KDC_ERR_PIN_EXPIRED (96), and KDC_ERR_PIN_REQUIRED (97) and key usage KEY_USAGE_OTP_REQUEST (45) are also defined.
A compromised KDC can mount a brute-force attack against short OTP values by iterating Client Key candidates and testing decryption of encData. Use of an iteration count in key derivation makes brute-force computationally infeasible within the OTP lifetime. Clients SHOULD choose an iteration count accordingly.
A large client-supplied iteration count can cause a denial-of-service attack against the KDC by forcing expensive key derivation. The KDC MUST reject authentication requests where the iteration count exceeds a locally configured maximum value.
In two-pass mode, replay protection relies on an external OTP server or timestamp replay cache rather than a KDC-generated nonce. OTPs generated solely from a client-generated challenge (without combining with time or counter) SHOULD NOT be supported in two-pass mode due to inability to detect replay.
Four-pass mode: (1) client sends initial AS-REQ → (2) KDC returns KRB-ERROR with PA-OTP-CHALLENGE → (3) client sends second AS-REQ with PA-OTP-REQUEST (encData = encrypted nonce) → (4) KDC returns AS-REP encrypted with Reply Key. Two-pass mode collapses steps 1–3: client includes PA-OTP-REQUEST with encData = encrypted timestamp in the initial AS-REQ without receiving a challenge.
OTP-TOKENINFO is an ASN.1 SEQUENCE carrying per-token parameters: OTPFlags (8 defined flag bits), optional otp-vendor (UTF8String), optional otp-challenge (OCTET STRING), optional otp-length (Int32), optional otp-format (OTPFormat INTEGER 0–4), optional otp-tokenID (OCTET STRING), optional otp-algID (AnyURI), optional supportedHashAlg (SEQUENCE OF AlgorithmIdentifier), and optional iterationCount (Int32).
OTPFlags is a KerberosFlags bit string with eight defined bits: reserved(0), nextOTP(1), combine(2), collect-pin(3), do-not-collect-pin(4), must-encrypt-nonce(5), separate-pin-required(6), check-digit(7). These flags appear in both PA-OTP-CHALLENGE/OTP-TOKENINFO and PA-OTP-REQUEST.
PA-OTP-ENC-REQUEST is an ASN.1 SEQUENCE containing a single nonce (OCTET STRING) field; it is encrypted under the Client Key with KEY_USAGE_OTP_REQUEST (45) and carried in the encData of a PA-OTP-REQUEST when responding to a PA-OTP-CHALLENGE.