1 /*
2  * totp.c - implementation of the OATH TOTP algorithm
3  * Copyright (C) 2011-2016 Simon Josefsson
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  *
20  */
21 
22 #include <config.h>
23 
24 #include "oath.h"
25 #include "hotp.h"
26 #include "aux.h"		/* _oath_strcmp_callback */
27 
28 /**
29  * oath_totp_generate:
30  * @secret: the shared secret string
31  * @secret_length: length of @secret
32  * @now: Unix time value to compute TOTP for
33  * @time_step_size: time step system parameter (typically 30)
34  * @start_offset: Unix time of when to start counting time steps (typically 0)
35  * @digits: number of requested digits in the OTP, excluding checksum
36  * @output_otp: output buffer, must have room for the output OTP plus zero
37  *
38  * Generate a one-time-password using the time-variant TOTP algorithm
39  * described in RFC 6238.  The input parameters are taken as time
40  * values.
41  *
42  * The system parameter @time_step_size describes how long the time
43  * window for each OTP is.  The recommended value is 30 seconds, and
44  * you can use the value 0 or the symbol
45  * %OATH_TOTP_DEFAULT_TIME_STEP_SIZE to indicate this.
46  *
47  * The system parameter @start_offset denote the Unix time when time
48  * steps are started to be counted.  The recommended value is 0, to
49  * fall back on the Unix epoch) and you can use the symbol
50  * %OATH_TOTP_DEFAULT_START_TIME to indicate this.
51  *
52  * The @output_otp buffer must have room for at least @digits
53  * characters, plus one for the terminating NUL.
54  *
55  * Currently only values 6, 7 and 8 for @digits are supported.  This
56  * restriction may be lifted in future versions.
57  *
58  * Returns: On success, %OATH_OK (zero) is returned, otherwise an
59  *   error code is returned.
60  *
61  * Since: 1.4.0
62  **/
63 int
oath_totp_generate(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,char * output_otp)64 oath_totp_generate (const char *secret,
65 		    size_t secret_length,
66 		    time_t now,
67 		    unsigned time_step_size,
68 		    time_t start_offset, unsigned digits, char *output_otp)
69 {
70   return oath_totp_generate2 (secret, secret_length, now, time_step_size,
71 			      start_offset, digits, 0, output_otp);
72 }
73 
74 /**
75  * oath_totp_generate2:
76  * @secret: the shared secret string
77  * @secret_length: length of @secret
78  * @now: Unix time value to compute TOTP for
79  * @time_step_size: time step system parameter (typically 30)
80  * @start_offset: Unix time of when to start counting time steps (typically 0)
81  * @digits: number of requested digits in the OTP, excluding checksum
82  * @flags: flags indicating mode, one of #oath_totp_flags
83  * @output_otp: output buffer, must have room for the output OTP plus zero
84  *
85  * Generate a one-time-password using the time-variant TOTP algorithm
86  * described in RFC 6238.  The input parameters are taken as time
87  * values.
88  *
89  * The system parameter @time_step_size describes how long the time
90  * window for each OTP is.  The recommended value is 30 seconds, and
91  * you can use the value 0 or the symbol
92  * %OATH_TOTP_DEFAULT_TIME_STEP_SIZE to indicate this.
93  *
94  * The system parameter @start_offset denote the Unix time when time
95  * steps are started to be counted.  The recommended value is 0, to
96  * fall back on the Unix epoch) and you can use the symbol
97  * %OATH_TOTP_DEFAULT_START_TIME to indicate this.
98  *
99  * The @output_otp buffer must have room for at least @digits
100  * characters, plus one for the terminating NUL.
101  *
102  * Currently only values 6, 7 and 8 for @digits are supported.  This
103  * restriction may be lifted in future versions.
104  *
105  * The @flags parameter may be used to change the MAC function, for
106  * example %OATH_TOTP_HMAC_SHA256 or %OATH_TOTP_HMAC_SHA512.
107  *
108  * Returns: On success, %OATH_OK (zero) is returned, otherwise an
109  *   error code is returned.
110  *
111  * Since: 2.6.0
112  **/
113 int
oath_totp_generate2(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,int flags,char * output_otp)114 oath_totp_generate2 (const char *secret,
115 		     size_t secret_length,
116 		     time_t now,
117 		     unsigned time_step_size,
118 		     time_t start_offset,
119 		     unsigned digits, int flags, char *output_otp)
120 {
121   uint64_t nts;
122 
123   if (time_step_size == 0)
124     time_step_size = OATH_TOTP_DEFAULT_TIME_STEP_SIZE;
125 
126   nts = (now - start_offset) / time_step_size;
127 
128   return _oath_hotp_generate2 (secret,
129 			       secret_length,
130 			       nts,
131 			       digits,
132 			       false, OATH_HOTP_DYNAMIC_TRUNCATION, flags,
133 			       output_otp);
134 }
135 
136 /**
137  * oath_totp_validate:
138  * @secret: the shared secret string
139  * @secret_length: length of @secret
140  * @now: Unix time value to validate TOTP for
141  * @time_step_size: time step system parameter (typically 30)
142  * @start_offset: Unix time of when to start counting time steps (typically 0)
143  * @window: how many OTPs after/before start OTP to test
144  * @otp: the OTP to validate.
145  *
146  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
147  *
148  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
149  * restrictions may be lifted in future versions, although some
150  * limitations are inherent in the protocol.
151  *
152  * Returns: Returns absolute value of position in OTP window (zero is
153  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
154  *   window, or an error code.
155  *
156  * Since: 1.6.0
157  **/
158 int
oath_totp_validate(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,size_t window,const char * otp)159 oath_totp_validate (const char *secret,
160 		    size_t secret_length,
161 		    time_t now,
162 		    unsigned time_step_size,
163 		    time_t start_offset, size_t window, const char *otp)
164 {
165   return oath_totp_validate3 (secret, secret_length, now, time_step_size,
166 			      start_offset, window, NULL, NULL, otp);
167 }
168 
169 /**
170  * oath_totp_validate_callback:
171  * @secret: the shared secret string
172  * @secret_length: length of @secret
173  * @now: Unix time value to compute TOTP for
174  * @time_step_size: time step system parameter (typically 30)
175  * @start_offset: Unix time of when to start counting time steps (typically 0)
176  * @window: how many OTPs after start counter to test
177  * @digits: number of requested digits in the OTP
178  * @strcmp_otp: function pointer to a strcmp-like function.
179  * @strcmp_handle: caller handle to be passed on to @strcmp_otp.
180  *
181  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
182  *
183  * Validation is implemented by generating a number of potential OTPs
184  * and performing a call to the @strcmp_otp function, to compare the
185  * potential OTP against the given @otp.  It has the following
186  * prototype:
187  *
188  * int (*oath_validate_strcmp_function) (void *handle, const char *test_otp);
189  *
190  * The function should be similar to strcmp in that it return 0 only
191  * on matches.  It differs by permitting use of negative return codes
192  * as indication of internal failures in the callback.  Positive
193  * values indicate OTP mismatch.
194  *
195  * This callback interface is useful when you cannot compare OTPs
196  * directly using normal strcmp, but instead for example only have a
197  * hashed OTP.  You would then typically pass in the hashed OTP in the
198  * @strcmp_handle and let your implementation of @strcmp_otp hash the
199  * test_otp OTP using the same hash, and then compare the results.
200  *
201  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
202  * restrictions may be lifted in future versions, although some
203  * limitations are inherent in the protocol.
204  *
205  * Returns: Returns position in OTP window (zero is first position),
206  *   or %OATH_INVALID_OTP if no OTP was found in OTP window, or an
207  *   error code.
208  *
209  * Since: 1.6.0
210  **/
211 int
oath_totp_validate_callback(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,size_t window,oath_validate_strcmp_function strcmp_otp,void * strcmp_handle)212 oath_totp_validate_callback (const char *secret,
213 			     size_t secret_length,
214 			     time_t now,
215 			     unsigned time_step_size,
216 			     time_t start_offset,
217 			     unsigned digits,
218 			     size_t window,
219 			     oath_validate_strcmp_function strcmp_otp,
220 			     void *strcmp_handle)
221 {
222   return oath_totp_validate4_callback (secret, secret_length, now,
223 				       time_step_size, start_offset,
224 				       digits, window, NULL, NULL, 0,
225 				       strcmp_otp, strcmp_handle);
226 }
227 
228 /**
229  * oath_totp_validate2:
230  * @secret: the shared secret string
231  * @secret_length: length of @secret
232  * @now: Unix time value to validate TOTP for
233  * @time_step_size: time step system parameter (typically 30)
234  * @start_offset: Unix time of when to start counting time steps (typically 0)
235  * @window: how many OTPs after/before start OTP to test
236  * @otp_pos: output search position in search window (may be NULL).
237  * @otp: the OTP to validate.
238  *
239  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
240  *
241  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
242  * restrictions may be lifted in future versions, although some
243  * limitations are inherent in the protocol.
244  *
245  * Returns: Returns absolute value of position in OTP window (zero is
246  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
247  *   window, or an error code.
248  *
249  * Since: 1.10.0
250  **/
251 int
oath_totp_validate2(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,size_t window,int * otp_pos,const char * otp)252 oath_totp_validate2 (const char *secret,
253 		     size_t secret_length,
254 		     time_t now,
255 		     unsigned time_step_size,
256 		     time_t start_offset,
257 		     size_t window, int *otp_pos, const char *otp)
258 {
259   return oath_totp_validate4_callback (secret, secret_length, now,
260 				       time_step_size, start_offset,
261 				       strlen (otp), window, otp_pos,
262 				       NULL, 0, _oath_strcmp_callback,
263 				       (void *) otp);
264 }
265 
266 /**
267  * oath_totp_validate2_callback:
268  * @secret: the shared secret string
269  * @secret_length: length of @secret
270  * @now: Unix time value to compute TOTP for
271  * @time_step_size: time step system parameter (typically 30)
272  * @start_offset: Unix time of when to start counting time steps (typically 0)
273  * @digits: number of requested digits in the OTP
274  * @window: how many OTPs after start counter to test
275  * @otp_pos: output search position in search window (may be NULL).
276  * @strcmp_otp: function pointer to a strcmp-like function.
277  * @strcmp_handle: caller handle to be passed on to @strcmp_otp.
278  *
279  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
280  *
281  * Validation is implemented by generating a number of potential OTPs
282  * and performing a call to the @strcmp_otp function, to compare the
283  * potential OTP against the given @otp.  It has the following
284  * prototype:
285  *
286  * int (*oath_validate_strcmp_function) (void *handle, const char *test_otp);
287  *
288  * The function should be similar to strcmp in that it return 0 only
289  * on matches.  It differs by permitting use of negative return codes
290  * as indication of internal failures in the callback.  Positive
291  * values indicate OTP mismatch.
292  *
293  * This callback interface is useful when you cannot compare OTPs
294  * directly using normal strcmp, but instead for example only have a
295  * hashed OTP.  You would then typically pass in the hashed OTP in the
296  * @strcmp_handle and let your implementation of @strcmp_otp hash the
297  * test_otp OTP using the same hash, and then compare the results.
298  *
299  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
300  * restrictions may be lifted in future versions, although some
301  * limitations are inherent in the protocol.
302  *
303  * Returns: Returns absolute value of position in OTP window (zero is
304  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
305  *   window, or an error code.
306  *
307  * Since: 1.10.0
308  **/
309 int
oath_totp_validate2_callback(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,size_t window,int * otp_pos,oath_validate_strcmp_function strcmp_otp,void * strcmp_handle)310 oath_totp_validate2_callback (const char *secret,
311 			      size_t secret_length,
312 			      time_t now,
313 			      unsigned time_step_size,
314 			      time_t start_offset,
315 			      unsigned digits,
316 			      size_t window,
317 			      int *otp_pos,
318 			      oath_validate_strcmp_function strcmp_otp,
319 			      void *strcmp_handle)
320 {
321   return oath_totp_validate4_callback (secret, secret_length, now,
322 				       time_step_size, start_offset,
323 				       digits, window, otp_pos, NULL,
324 				       0, strcmp_otp, strcmp_handle);
325 }
326 
327 /**
328  * oath_totp_validate3:
329  * @secret: the shared secret string
330  * @secret_length: length of @secret
331  * @now: Unix time value to validate TOTP for
332  * @time_step_size: time step system parameter (typically 30)
333  * @start_offset: Unix time of when to start counting time steps (typically 0)
334  * @window: how many OTPs after/before start OTP to test
335  * @otp_pos: output search position in search window (may be NULL).
336  * @otp_counter: counter value used to calculate OTP value (may be NULL).
337  * @otp: the OTP to validate.
338  *
339  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
340  *
341  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
342  * restrictions may be lifted in future versions, although some
343  * limitations are inherent in the protocol.
344  *
345  * Returns: Returns absolute value of position in OTP window (zero is
346  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
347  *   window, or an error code.
348  *
349  * Since: 2.4.0
350  **/
351 int
oath_totp_validate3(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,size_t window,int * otp_pos,uint64_t * otp_counter,const char * otp)352 oath_totp_validate3 (const char *secret,
353 		     size_t secret_length,
354 		     time_t now,
355 		     unsigned time_step_size,
356 		     time_t start_offset,
357 		     size_t window,
358 		     int *otp_pos, uint64_t * otp_counter, const char *otp)
359 {
360   return oath_totp_validate4_callback (secret, secret_length, now,
361 				       time_step_size, start_offset,
362 				       strlen (otp), window, otp_pos,
363 				       otp_counter, 0, _oath_strcmp_callback,
364 				       (void *) otp);
365 }
366 
367 /**
368  * oath_totp_validate3_callback:
369  * @secret: the shared secret string
370  * @secret_length: length of @secret
371  * @now: Unix time value to compute TOTP for
372  * @time_step_size: time step system parameter (typically 30)
373  * @start_offset: Unix time of when to start counting time steps (typically 0)
374  * @digits: number of requested digits in the OTP
375  * @window: how many OTPs after start counter to test
376  * @otp_pos: output search position in search window (may be NULL).
377  * @otp_counter: counter value used to calculate OTP value (may be NULL).
378  * @strcmp_otp: function pointer to a strcmp-like function.
379  * @strcmp_handle: caller handle to be passed on to @strcmp_otp.
380  *
381  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
382  *
383  * Validation is implemented by generating a number of potential OTPs
384  * and performing a call to the @strcmp_otp function, to compare the
385  * potential OTP against the given @otp.  It has the following
386  * prototype:
387  *
388  * int (*oath_validate_strcmp_function) (void *handle, const char *test_otp);
389  *
390  * The function should be similar to strcmp in that it return 0 only
391  * on matches.  It differs by permitting use of negative return codes
392  * as indication of internal failures in the callback.  Positive
393  * values indicate OTP mismatch.
394  *
395  * This callback interface is useful when you cannot compare OTPs
396  * directly using normal strcmp, but instead for example only have a
397  * hashed OTP.  You would then typically pass in the hashed OTP in the
398  * @strcmp_handle and let your implementation of @strcmp_otp hash the
399  * test_otp OTP using the same hash, and then compare the results.
400  *
401  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
402  * restrictions may be lifted in future versions, although some
403  * limitations are inherent in the protocol.
404  *
405  * Returns: Returns absolute value of position in OTP window (zero is
406  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
407  *   window, or an error code.
408  *
409  * Since: 2.4.0
410  **/
411 int
oath_totp_validate3_callback(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,size_t window,int * otp_pos,uint64_t * otp_counter,oath_validate_strcmp_function strcmp_otp,void * strcmp_handle)412 oath_totp_validate3_callback (const char *secret,
413 			      size_t secret_length,
414 			      time_t now,
415 			      unsigned time_step_size,
416 			      time_t start_offset,
417 			      unsigned digits,
418 			      size_t window,
419 			      int *otp_pos,
420 			      uint64_t * otp_counter,
421 			      oath_validate_strcmp_function strcmp_otp,
422 			      void *strcmp_handle)
423 {
424   return oath_totp_validate4_callback (secret, secret_length, now,
425 				       time_step_size, start_offset,
426 				       digits, window, otp_pos,
427 				       otp_counter, 0, strcmp_otp,
428 				       strcmp_handle);
429 }
430 
431 /**
432  * oath_totp_validate4:
433  * @secret: the shared secret string
434  * @secret_length: length of @secret
435  * @now: Unix time value to validate TOTP for
436  * @time_step_size: time step system parameter (typically 30)
437  * @start_offset: Unix time of when to start counting time steps (typically 0)
438  * @window: how many OTPs after/before start OTP to test
439  * @otp_pos: output search position in search window (may be NULL).
440  * @otp_counter: counter value used to calculate OTP value (may be NULL).
441  * @flags: flags indicating mode, one of #oath_totp_flags
442  * @otp: the OTP to validate.
443  *
444  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
445  *
446  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
447  * restrictions may be lifted in future versions, although some
448  * limitations are inherent in the protocol.
449  *
450  * The @flags parameter may be used to change the MAC function, for
451  * example %OATH_TOTP_HMAC_SHA256 or %OATH_TOTP_HMAC_SHA512.
452  *
453  * Returns: Returns absolute value of position in OTP window (zero is
454  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
455  *   window, or an error code.
456  *
457  * Since: 2.6.0
458  **/
459 int
oath_totp_validate4(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,size_t window,int * otp_pos,uint64_t * otp_counter,int flags,const char * otp)460 oath_totp_validate4 (const char *secret,
461 		     size_t secret_length,
462 		     time_t now,
463 		     unsigned time_step_size,
464 		     time_t start_offset,
465 		     size_t window,
466 		     int *otp_pos,
467 		     uint64_t * otp_counter, int flags, const char *otp)
468 {
469   return oath_totp_validate4_callback (secret, secret_length, now,
470 				       time_step_size, start_offset,
471 				       strlen (otp), window, otp_pos,
472 				       otp_counter, flags,
473 				       _oath_strcmp_callback, (void *) otp);
474 }
475 
476 /**
477  * oath_totp_validate4_callback:
478  * @secret: the shared secret string
479  * @secret_length: length of @secret
480  * @now: Unix time value to compute TOTP for
481  * @time_step_size: time step system parameter (typically 30)
482  * @start_offset: Unix time of when to start counting time steps (typically 0)
483  * @digits: number of requested digits in the OTP
484  * @window: how many OTPs after start counter to test
485  * @otp_pos: output search position in search window (may be NULL).
486  * @otp_counter: counter value used to calculate OTP value (may be NULL).
487  * @flags: flags indicating mode, one of #oath_totp_flags
488  * @strcmp_otp: function pointer to a strcmp-like function.
489  * @strcmp_handle: caller handle to be passed on to @strcmp_otp.
490  *
491  * Validate an OTP according to OATH TOTP algorithm per RFC 6238.
492  *
493  * Validation is implemented by generating a number of potential OTPs
494  * and performing a call to the @strcmp_otp function, to compare the
495  * potential OTP against the given @otp.  It has the following
496  * prototype:
497  *
498  * int (*oath_validate_strcmp_function) (void *handle, const char *test_otp);
499  *
500  * The function should be similar to strcmp in that it return 0 only
501  * on matches.  It differs by permitting use of negative return codes
502  * as indication of internal failures in the callback.  Positive
503  * values indicate OTP mismatch.
504  *
505  * This callback interface is useful when you cannot compare OTPs
506  * directly using normal strcmp, but instead for example only have a
507  * hashed OTP.  You would then typically pass in the hashed OTP in the
508  * @strcmp_handle and let your implementation of @strcmp_otp hash the
509  * test_otp OTP using the same hash, and then compare the results.
510  *
511  * Currently only OTP lengths of 6, 7 or 8 digits are supported.  This
512  * restrictions may be lifted in future versions, although some
513  * limitations are inherent in the protocol.
514  *
515  * The @flags parameter may be used to change the MAC function, for
516  * example %OATH_TOTP_HMAC_SHA256 or %OATH_TOTP_HMAC_SHA512.
517  *
518  * Returns: Returns absolute value of position in OTP window (zero is
519  *   first position), or %OATH_INVALID_OTP if no OTP was found in OTP
520  *   window, or an error code.
521  *
522  * Since: 2.6.0
523  **/
524 int
oath_totp_validate4_callback(const char * secret,size_t secret_length,time_t now,unsigned time_step_size,time_t start_offset,unsigned digits,size_t window,int * otp_pos,uint64_t * otp_counter,int flags,oath_validate_strcmp_function strcmp_otp,void * strcmp_handle)525 oath_totp_validate4_callback (const char *secret,
526 			      size_t secret_length,
527 			      time_t now,
528 			      unsigned time_step_size,
529 			      time_t start_offset,
530 			      unsigned digits,
531 			      size_t window,
532 			      int *otp_pos,
533 			      uint64_t * otp_counter,
534 			      int flags,
535 			      oath_validate_strcmp_function strcmp_otp,
536 			      void *strcmp_handle)
537 {
538   unsigned iter = 0;
539   char tmp_otp[10];
540   int rc;
541   uint64_t nts;
542 
543   if (time_step_size == 0)
544     time_step_size = OATH_TOTP_DEFAULT_TIME_STEP_SIZE;
545 
546   nts = (now - start_offset) / time_step_size;
547 
548   do
549     {
550       rc = _oath_hotp_generate2 (secret,
551 				 secret_length,
552 				 nts + iter,
553 				 digits,
554 				 false,
555 				 OATH_HOTP_DYNAMIC_TRUNCATION,
556 				 flags, tmp_otp);
557       if (rc != OATH_OK)
558 	return rc;
559 
560       if ((rc = strcmp_otp (strcmp_handle, tmp_otp)) == 0)
561 	{
562 	  if (otp_counter)
563 	    *otp_counter = nts + iter;
564 	  if (otp_pos)
565 	    *otp_pos = iter;
566 	  return iter;
567 	}
568       if (rc < 0)
569 	return OATH_STRCMP_ERROR;
570 
571       if (iter > 0)
572 	{
573 	  rc = _oath_hotp_generate2 (secret,
574 				     secret_length,
575 				     nts - iter,
576 				     digits,
577 				     false,
578 				     OATH_HOTP_DYNAMIC_TRUNCATION,
579 				     flags, tmp_otp);
580 	  if (rc != OATH_OK)
581 	    return rc;
582 
583 	  if ((rc = strcmp_otp (strcmp_handle, tmp_otp)) == 0)
584 	    {
585 	      if (otp_counter)
586 		*otp_counter = nts - iter;
587 	      if (otp_pos)
588 		*otp_pos = -iter;
589 	      return iter;
590 	    }
591 	  if (rc < 0)
592 	    return OATH_STRCMP_ERROR;
593 	}
594     }
595   while (window - iter++ > 0);
596 
597   return OATH_INVALID_OTP;
598 }
599