docs: def validate_oath_hotp(self, params):
      """
      Validate OATH-HOTP code using YubiHSM HMAC-SHA1 hashing with token keys
      secured in AEAD's that we have stored in an SQLite3 database.
      """
      from_key = params["hotp"][0]
      if not re.match(hotp_valid_input, from_key):
          self.log_error("IN: %s, Invalid OATH-HOTP OTP" % (params))
          return "ERR Invalid OATH-HOTP OTP"
      uid, otp, = get_oath_hotp_bits(params)
      if not uid or not otp:
          self.log_error("IN: %s, could not get UID/OTP ('%s'/'%s')" % (params, uid, otp))
          return "ERR Invalid OATH-HOTP input"
      if args.debug:
          print "OATH-HOTP uid %s, OTP %s" % (uid, otp)
  
      # Fetch counter value for `uid' from database
      try:
          db = ValOathDb(args.db_file)
          entry = db.get(uid)
      except Exception, e:
          self.log_error("IN: %s, database error : '%s'" % (params, e))
          return "ERR Internal error"
  
      # Check for correct OATH-HOTP OTP
      nonce = entry.data["nonce"].decode('hex')
      aead = entry.data["aead"].decode('hex')
      new_counter = pyhsm.oath_hotp.search_for_oath_code(hsm, entry.data["key_handle"], nonce, aead, \
                                                             entry.data["oath_c"], otp, args.look_ahead)
      if args.debug:
          print "OATH-HOTP %i..%i -> new C == %s" \
              % (entry.data["oath_c"], entry.data["oath_c"] + args.look_ahead, new_counter)
      if type(new_counter) != int:
          # XXX increase 'throttling parameter' to make brute forcing harder/impossible
          return "ERR Could not validate OATH-HOTP OTP"
      try:
          # Must successfully store new_counter before we return OK
          if db.update_oath_hotp_c(entry, new_counter):
              return "OK counter=%04x" % (new_counter)
          else:
              return "ERR replayed OATH-HOTP"
      except Exception, e:
          self.log_error("IN: %s, database error updating counter : %s" % (params, e))
          return "ERR Internal error"