Hi, thanks for the reply. For the record, I used to deploy these systems for a living.
The key is destroyed. That's the only way they can still use 3DES as the shared key, and still be FIPS compatible. When the key or card is issued, the AS generates a seed. This seed is known to both the token and the authenticator. Two other things are shared/known by both parties, the EC (Event Counter, the number of times the device has been used, randomly initialised), and the TC (Time Counter, ticks with roughly every second, most AS systems account for drift). The seed is used by both the AS and the token to generate a common (and exactly the same 3DES key).
Every time an OTP is generated, the last digit of the EC and the TC are prefixed to the actual OTP. As soon as the OTP is generated, the 3DES shared key is overwritten with a new one, which was seeded based off the previous 3DES key. The same key is never used twice to generate an OTP.
How does the server figure it out? Well, when the server receives an AA using an OTP, it looks at the first digit. It then looks up in its database what the last used EC was, say 3320, but the digit it read was a 4. It knows it has to test 3324, 3334, 3344, 3354, 3364, up to the upper limit before the token is considered "desynchronised". Same thing for the TC, except that this one is just current_time +/- token drift. Again, only the last digit is provided, which gives the AS two or three values max to check. Then comes the OTP, which the AS computes on the fly, for every EC/TC combination it calculated. If none match, the AA is rejected, and the token flagged.
If, however, the AS validates the AA, then it updates the EC/TC in its records, and also accounts for the drift of the token. It then also stores the new key, as defined by the EC and TC.
The token doesn't know whether the AS accepted the AA or not, which is why it overwrites its own key every single time.
AS: Authentication Server
AA: Authentication Attempt
The TC upper limit is usually 30. The EC range is roughly 1.5 minutes each way.
: Say the OTP is 42000000, the in-database EC is 3320, then the AS has to run key = f( f( f( f( key, 3321), 3322), 3323), 3324). The TC is not used to generate the next key, for obvious reasons.