Major cleanup and API overhaul.

- The API has been redesigned so the caller is now responsible for allocating storage.
- A few more macros and typedefs have been added to clean up the namespace.
- Key parameter validation has been strengthened.
This commit is contained in:
Dag-Erling Smørgrav 2018-04-26 00:07:55 +02:00
parent 54c67f337a
commit 48fc358df7
15 changed files with 126 additions and 331 deletions

View file

@ -44,27 +44,23 @@ CRYB_BEGIN
const char *cryb_oath_version(void); const char *cryb_oath_version(void);
#define oath_key_alloc cryb_oath_key_alloc
#define oath_key_create cryb_oath_key_create #define oath_key_create cryb_oath_key_create
#define oath_key_destroy cryb_oath_key_destroy
#define oath_key_dummy cryb_oath_key_dummy #define oath_key_dummy cryb_oath_key_dummy
#define oath_key_free cryb_oath_key_free
#define oath_key_from_uri cryb_oath_key_from_uri #define oath_key_from_uri cryb_oath_key_from_uri
#define oath_key_to_uri cryb_oath_key_to_uri #define oath_key_to_uri cryb_oath_key_to_uri
#define oath_mode_name cryb_oath_mode_name #define oath_mode_name cryb_oath_mode_name
#define oath_mode_value cryb_oath_mode_value #define oath_mode_value cryb_oath_mode_value
struct oath_key *oath_key_alloc(void); int oath_key_create(oath_key *, oath_mode, oath_hash, unsigned int,
struct oath_key *oath_key_create(const char *, const char *, const char *, const char *, const char *, size_t);
enum oath_mode, enum oath_hash, const char *, size_t); void oath_key_destroy(oath_key *);
void oath_key_free(struct oath_key *); int oath_key_dummy(oath_key *, oath_mode, oath_hash, unsigned int);
struct oath_key *oath_key_from_uri(const char *); int oath_key_from_uri(oath_key *, const char *);
struct oath_key *oath_key_from_file(const char *); char *oath_key_to_uri(const oath_key *);
char *oath_key_to_uri(const struct oath_key *);
struct oath_key *oath_key_dummy(enum oath_mode, enum oath_hash, unsigned int); const char *oath_mode_name(oath_mode);
oath_mode oath_mode_value(const char *);
const char *oath_mode_name(enum oath_mode);
enum oath_mode oath_mode_value(const char *);
CRYB_END CRYB_END

View file

@ -36,28 +36,38 @@
CRYB_BEGIN CRYB_BEGIN
#define oath_mode cryb_oath_mode
#define oath_hash cryb_oath_hash
/* /*
* OATH modes * OATH modes
*/ */
enum oath_mode { typedef enum {
om_undef, /* not set / default */ om_undef, /* not set / default */
om_hotp, /* RFC 4226 HOTP */ om_hotp, /* RFC 4226 HOTP */
om_totp, /* RFC 6238 TOTP */ om_totp, /* RFC 6238 TOTP */
om_ocra, /* RFC 6287 OCRA */ om_ocra, /* RFC 6287 OCRA */
om_max om_max
}; } oath_mode;
/* /*
* Hash functions * Hash functions
*/ */
enum oath_hash { typedef enum {
oh_undef, /* not set / default */ oh_undef, /* not set / default */
oh_md5, /* RFC 1321 MD5 */ oh_md5, /* RFC 1321 MD5 */
oh_sha1, /* FIPS 180 SHA-1 */ oh_sha1, /* FIPS 180 SHA-1 */
oh_sha256, /* FIPS 180 SHA-256 */ oh_sha256, /* FIPS 180 SHA-256 */
oh_sha512, /* FIPS 180 SHA-512 */ oh_sha512, /* FIPS 180 SHA-512 */
oh_max oh_max
}; } oath_hash;
/*
* Minimum and default number of digits as per RFC 4226.
*/
#define OATH_MIN_DIGITS 6
#define OATH_DEF_DIGITS 6
#define OATH_MAX_DIGITS 9
/* /*
* Default time step for TOTP: 30 seconds. * Default time step for TOTP: 30 seconds.
@ -71,9 +81,12 @@ enum oath_hash {
#define OATH_MAX_TIMESTEP 600 #define OATH_MAX_TIMESTEP 600
/* /*
* Maximum key length in bytes. HMAC has a 64-byte block size; if the key * Minimum, default and maximum key lengths in bytes as per RFC 4226.
* K is longer than that, HMAC derives a new key K' = H(K). * HMAC has a 64-byte block size; if the key K is longer than that, HMAC
* derives a new key K' = H(K).
*/ */
#define OATH_MIN_KEYLEN 16
#define OATH_DEF_KEYLEN 20
#define OATH_MAX_KEYLEN 64 #define OATH_MAX_KEYLEN 64
/* /*

View file

@ -45,8 +45,8 @@ CRYB_BEGIN
#define oath_hotp_match cryb_oath_hotp_match #define oath_hotp_match cryb_oath_hotp_match
unsigned int oath_hotp(const uint8_t *, size_t, uint64_t, unsigned int); unsigned int oath_hotp(const uint8_t *, size_t, uint64_t, unsigned int);
unsigned int oath_hotp_current(struct oath_key *); unsigned int oath_hotp_current(oath_key *);
int oath_hotp_match(struct oath_key *, unsigned int, int); int oath_hotp_match(oath_key *, unsigned int, int);
CRYB_END CRYB_END

View file

@ -45,8 +45,8 @@ CRYB_BEGIN
#define oath_totp_match cryb_oath_totp_match #define oath_totp_match cryb_oath_totp_match
unsigned int oath_totp(const uint8_t *, size_t, unsigned int); unsigned int oath_totp(const uint8_t *, size_t, unsigned int);
unsigned int oath_totp_current(const struct oath_key *); unsigned int oath_totp_current(const oath_key *);
int oath_totp_match(struct oath_key *, unsigned int, int); int oath_totp_match(oath_key *, unsigned int, int);
CRYB_END CRYB_END

View file

@ -36,12 +36,15 @@
CRYB_BEGIN CRYB_BEGIN
#define oath_key cryb_oath_key
/* /*
* OATH key and associated parameters * OATH key and associated parameters
*/ */
struct oath_key { typedef struct {
/* mode and parameters */ /* mode and parameters */
enum oath_mode mode; oath_mode mode;
oath_hash hash;
unsigned int digits; unsigned int digits;
uint64_t counter; /* HOTP only */ uint64_t counter; /* HOTP only */
unsigned int timestep; /* TOTP only - in seconds */ unsigned int timestep; /* TOTP only - in seconds */
@ -49,11 +52,6 @@ struct oath_key {
/* housekeeping */ /* housekeeping */
unsigned int dummy:1; /* dummy key, always fail */ unsigned int dummy:1; /* dummy key, always fail */
unsigned int mapped:1; /* allocated with mmap() */
unsigned int locked:1; /* locked / wired with madvise() */
/* hash algorithm */
enum oath_hash hash;
/* issuer */ /* issuer */
size_t issuerlen; /* bytes incl. NUL */ size_t issuerlen; /* bytes incl. NUL */
@ -66,7 +64,7 @@ struct oath_key {
/* key */ /* key */
size_t keylen; /* bytes */ size_t keylen; /* bytes */
uint8_t key[OATH_MAX_KEYLEN]; uint8_t key[OATH_MAX_KEYLEN];
}; } oath_key;
CRYB_END CRYB_END

View file

@ -5,11 +5,11 @@ lib_LTLIBRARIES = libcryb-oath.la
libcryb_oath_la_SOURCES = \ libcryb_oath_la_SOURCES = \
cryb_oath_hotp.c \ cryb_oath_hotp.c \
cryb_oath_totp.c \ cryb_oath_totp.c \
cryb_oath_key_alloc.c \ \
cryb_oath_key_create.c \ cryb_oath_key_create.c \
cryb_oath_key_destroy.c \
cryb_oath_key_dummy.c \ cryb_oath_key_dummy.c \
cryb_oath_key_from_uri.c \ cryb_oath_key_from_uri.c \
cryb_oath_key_free.c \
cryb_oath_key_to_uri.c \ cryb_oath_key_to_uri.c \
cryb_oath_mode.c \ cryb_oath_mode.c \
\ \

View file

@ -85,7 +85,7 @@ oath_hotp(const uint8_t *K, size_t Klen, uint64_t seq, unsigned int Digit)
* Computes the current code for the given key and advances the counter. * Computes the current code for the given key and advances the counter.
*/ */
unsigned int unsigned int
oath_hotp_current(struct oath_key *k) oath_hotp_current(oath_key *k)
{ {
unsigned int code; unsigned int code;
@ -106,7 +106,7 @@ oath_hotp_current(struct oath_key *k)
* error occurred. Also advances the counter if there was a match. * error occurred. Also advances the counter if there was a match.
*/ */
int int
oath_hotp_match(struct oath_key *k, unsigned int response, int window) oath_hotp_match(oath_key *k, unsigned int response, int window)
{ {
unsigned int code; unsigned int code;

View file

@ -1,80 +0,0 @@
/*-
* Copyright (c) 2013 The University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "cryb/impl.h"
#include <sys/mman.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <cryb/oath.h>
/*
* OATH
*
* Allocates an OATH key structure
*/
struct oath_key *
oath_key_alloc(void)
{
struct oath_key *key;
int prot, flags;
prot = PROT_READ|PROT_WRITE;
flags = MAP_ANON;
#ifdef MAP_NOCORE
flags |= MAP_NOCORE;
#endif
if ((key = mmap(NULL, sizeof *key, prot, flags, -1, 0)) != NULL) {
memset(key, 0, sizeof *key);
key->mapped = 1;
if (mlock(key, sizeof *key) == 0)
key->locked = 1;
} else {
/* openpam_log(PAM_LOG_ERROR, "mmap(): %m"); */
if ((key = calloc(sizeof *key, 1)) == NULL) {
/* openpam_log(PAM_LOG_ERROR, "malloc(): %m") */;
}
}
return (key);
}
/**
* The =oath_key_alloc function allocates and initializes an OATH key
* structure.
*
* Keys allocated with =oath_key_alloc must be freed using =oath_key_free.
*
* >oath_key_free
*
* AUTHOR UIO
*/

View file

@ -36,149 +36,79 @@
#include <cryb/oath.h> #include <cryb/oath.h>
#include <cryb/rand.h> #include <cryb/rand.h>
#include <cryb/strlcpy.h>
/* /*
* OATH * Initialize an OATH key with the specified parameters.
*
* Creates an OATH key with the specified parameters
*/ */
int
struct oath_key * oath_key_create(oath_key *ok,
oath_key_create(const char *issuer, const char *label, oath_mode mode, oath_hash hash, unsigned int digits,
enum oath_mode mode, enum oath_hash hash, const char *issuer, const char *label,
const char *keydata, size_t keylen) const char *keydata, size_t keylen)
{ {
char keybuf[OATH_MAX_KEYLEN];
struct oath_key *key; memset(ok, 0, sizeof *ok);
int issuerlen, labellen;
/* check issuer */ /* check issuer */
if (issuer == NULL || if (issuer == NULL ||
(issuerlen = strlen(issuer)) >= OATH_MAX_ISSUERLEN) strlcpy(ok->issuer, issuer, sizeof ok->issuer) >= sizeof ok->issuer)
return (NULL); goto fail;
/* check label */ /* check label */
if (label == NULL || if (label == NULL ||
(labellen = strlen(label)) >= OATH_MAX_LABELLEN) strlcpy(ok->label, label, sizeof ok->label) >= sizeof ok->label)
return (NULL); goto fail;
/* check key length */
if (keylen > OATH_MAX_KEYLEN ||
(keydata != NULL && keylen == 0))
return (NULL);
if (keylen == 0)
keylen = 20;
/* check mode */ /* check mode */
switch (mode) { switch (mode) {
case om_hotp:
case om_totp: case om_totp:
ok->timestep = 30;
/* fall through */
case om_hotp:
ok->mode = mode;
break; break;
default: default:
return (NULL); goto fail;
} }
/* check hash */ /* check hash */
switch (hash) { switch (hash) {
case oh_undef: case oh_undef:
hash = oh_sha1; hash = oh_sha1;
break; /* fall through */
case oh_md5: case oh_md5:
case oh_sha1: case oh_sha1:
case oh_sha256: case oh_sha256:
case oh_sha512: case oh_sha512:
ok->hash = hash;
break; break;
default: default:
return (NULL); goto fail;
} }
/* generate key data if necessary */ /* check digits */
if (keydata == NULL) { if (digits == 0)
if (rand_bytes((uint8_t *)keybuf, keylen) != (ssize_t)keylen) digits = OATH_DEF_DIGITS;
return (NULL); if (digits < OATH_MIN_DIGITS || digits > OATH_MAX_DIGITS)
keydata = keybuf; goto fail;
} ok->digits = digits;
/* allocate */ /* check key length */
if ((key = oath_key_alloc()) == NULL) if (keydata == NULL && keylen == 0)
return (NULL); keylen = OATH_DEF_KEYLEN;
if (keylen < OATH_MIN_KEYLEN || keylen > OATH_MAX_KEYLEN)
goto fail;
ok->keylen = keylen;
/* issuer */ /* copy or generate key */
memcpy(key->issuer, issuer, issuerlen); if (keydata != NULL)
key->issuer[issuerlen] = 0; memcpy(ok->key, keydata, ok->keylen);
key->issuerlen = issuerlen; else if (rand_bytes(ok->key, ok->keylen) != (ssize_t)ok->keylen)
goto fail;
/* label */ return (0);
memcpy(key->label, label, labellen); fail:
key->label[labellen] = 0; memset(ok, 0, sizeof *ok);
key->labellen = labellen; return (-1);
/* mode and hash */
key->mode = mode;
key->hash = hash;
/* default parameters */
key->digits = 6;
if (key->mode == om_totp)
key->timestep = 30;
/* key */
memcpy(key->key, keydata, keylen);
key->keylen = keylen;
return (key);
} }
/**
* The =oath_key_create function allocates and initializes an OATH key
* structure with the specified parameters.
*
* The =label parameter must point to a string describing the key.
*
* The =mode parameter indicates the OTP algorithm to use:
*
* ;om_hotp:
* RFC 4226 HOTP
* ;om_totp:
* RFC 6238 TOTP
*
* The =hash parameter indicates which hash algorithm to use:
*
* ;oh_md5:
* RFC 1321 MD5
* ;oh_sha1:
* RFC 3174 SHA-1
* ;oh_sha256:
* RFC 6234 SHA-256
* ;oh_sha512:
* RFC 6234 SHA-512
*
* If =hash is ;oh_undef, the default algorithm (SHA-1) is used.
*
* The =keydata parameter should point to a buffer containing the raw key
* to use.
* If =keydata is NULL, a key will be randomly generated.
* Note that the strength of the generated key is dependent on the
* strength of the operating system's pseudo-random number generator.
*
* The =keylen parameter specifies the length of the provided (or
* generated) key in bytes.
* Note that some OATH HOTP / TOTP implementations do not support key
* lengths that are not a multiple of 20 bits (5 bytes).
* If =keydata is NULL and =keylen is 0, a hardcoded default of 160 bits
* (20 bytes) is used.
*
* The following key parameters are set to hardcoded default values and
* can be changed after key creation:
*
* - For HOTP keys, the initial counter value is set to 0.
* - For TOTP keys, the timestep is set to 30 seconds.
* - For both HOTP and TOTP keys, the number of digits is set to 6.
*
* Keys created with =oath_key_create must be freed using =oath_key_free.
*
* >oath_key_alloc
* >oath_key_free
*
* AUTHOR UIO
*/

View file

@ -1,5 +1,6 @@
/*- /*-
* Copyright (c) 2013 The University of Oslo * Copyright (c) 2013 The University of Oslo
* Copyright (c) 2018 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,38 +36,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cryb/memset_s.h>
#include <cryb/oath.h> #include <cryb/oath.h>
/* /*
* OATH * Wipes an OATH key structure.
*
* Wipes and frees an OATH key structure
*/ */
void void
oath_key_free(struct oath_key *key) oath_key_destroy(oath_key *key)
{ {
int mapped, locked;
if (key != NULL) { if (key != NULL)
mapped = key->mapped; memset_s(key, 0, sizeof *key, sizeof *key);
locked = key->locked;
memset(key, 0, sizeof *key);
if (mapped) {
if (locked)
munlock(key, sizeof *key);
munmap(key, sizeof *key);
} else {
free(key);
}
}
} }
/**
* The =oath_key_free function wipes and frees an OATH key structure which
* was previously allocated using the =oath_key_alloc function.
*
* >oath_key_alloc
*
* AUTHOR UIO
*/

View file

@ -33,43 +33,27 @@
#include <string.h> #include <string.h>
#include <cryb/oath.h> #include <cryb/oath.h>
#include <cryb/strlcpy.h>
/* /*
* OATH * Initialize an OATH key with dummy parameters.
*
* Creates a dummy OATH key structure
*/ */
int
struct oath_key * oath_key_dummy(oath_key *ok, oath_mode mode, oath_hash hash,
oath_key_dummy(enum oath_mode mode, enum oath_hash hash, unsigned int digits) unsigned int digits)
{ {
struct oath_key *key;
if ((key = oath_key_alloc()) == NULL) memset(ok, 0, sizeof *ok);
return (NULL); ok->dummy = 1;
key->dummy = 1; ok->mode = mode;
key->mode = mode; ok->hash = hash;
key->digits = digits; ok->digits = digits;
key->counter = 0; ok->timestep = 30;
key->timestep = 30; ok->labellen =
key->hash = hash; strlcpy(ok->issuer, OATH_DUMMY_LABEL, sizeof ok->label);
memcpy(key->issuer, OATH_DUMMY_ISSUER, sizeof OATH_DUMMY_ISSUER); ok->issuerlen =
key->issuerlen = sizeof OATH_DUMMY_ISSUER - 1; strlcpy(ok->issuer, OATH_DUMMY_ISSUER, sizeof ok->issuer);
memcpy(key->label, OATH_DUMMY_LABEL, sizeof OATH_DUMMY_LABEL); ok->keylen = sizeof ok->key;
key->labellen = sizeof OATH_DUMMY_LABEL - 1; memset(ok->key, 0xff, ok->keylen);
key->keylen = sizeof key->key; return (0);
return (key);
} }
/**
* The =oath_key_dummy function allocates and initializes a dummy OATH key
* structure.
* Authentication attempts using a dummy key will always fail.
*
* Keys allocated with =oath_key_dummy must be freed using =oath_key_free.
*
* >oath_key_alloc
* >oath_key_free
*
* AUTHOR UIO
*/

View file

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2013-2016 The University of Oslo * Copyright (c) 2013-2016 The University of Oslo
* Copyright (c) 2016-2017 Dag-Erling Smørgrav * Copyright (c) 2016-2018 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,30 +33,27 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#include <cryb/oath.h>
#include <cryb/rfc3986.h> #include <cryb/rfc3986.h>
#include <cryb/rfc4648.h> #include <cryb/rfc4648.h>
#include <cryb/strlcmp.h> #include <cryb/strlcmp.h>
#include <cryb/strlcpy.h> #include <cryb/strlcpy.h>
#include <cryb/oath.h>
/* /*
* OATH * Initializes an OATH key with the parameters from a Google otpauth URI.
* *
* Creates an OATH key from a Google otpauth URI * https://github.com/google/google-authenticator/wiki/Key-Uri-Format
*/ */
int
struct oath_key * oath_key_from_uri(oath_key *key, const char *uri)
oath_key_from_uri(const char *uri)
{ {
char name[64], value[256]; char name[64], value[256];
size_t namelen, valuelen; size_t namelen, valuelen;
struct oath_key *key;
const char *p, *q, *r; const char *p, *q, *r;
uintmax_t n; uintmax_t n;
char *e; char *e;
if ((key = oath_key_alloc()) == NULL) memset(key, 0, sizeof *key);
return (NULL);
/* check method */ /* check method */
p = uri; p = uri;
@ -109,7 +106,8 @@ oath_key_from_uri(const char *uri)
/* dupe */ /* dupe */
goto invalid; goto invalid;
key->keylen = sizeof key->key; key->keylen = sizeof key->key;
if (base32_decode(value, valuelen, key->key, &key->keylen) != 0) if (base32_decode(value, valuelen, key->key,
&key->keylen) != 0)
goto invalid; goto invalid;
} else if (strcmp("algorithm", name) == 0) { } else if (strcmp("algorithm", name) == 0) {
if (key->hash != oh_undef) if (key->hash != oh_undef)
@ -189,8 +187,7 @@ oath_key_from_uri(const char *uri)
key->lastused = 0; key->lastused = 0;
} else { } else {
/* unreachable */ /* unreachable */
oath_key_free(key); goto invalid;
return (NULL);
} }
if (key->hash == oh_undef) if (key->hash == oh_undef)
key->hash = oh_sha1; key->hash = oh_sha1;
@ -198,31 +195,9 @@ oath_key_from_uri(const char *uri)
key->digits = 6; key->digits = 6;
if (key->keylen == 0) if (key->keylen == 0)
goto invalid; goto invalid;
return (key); return (0);
invalid: invalid:
// openpam_log(PAM_LOG_NOTICE, "invalid OATH URI: %s", uri); memset(key, 0, sizeof *key);
oath_key_free(key); return (-1);
return (NULL);
} }
/**
* The =oath_key_from_uri function parses a Google otpauth URI into a key
* structure.
*
* The =uri parameter points to a NUL-terminated string containing the
* URI.
*
* Keys created with =oath_key_from_uri must be freed using
* =oath_key_free.
*
* >oath_key_alloc
* >oath_key_free
* >oath_key_to_uri
*
* REFERENCES
*
* https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
*
* AUTHOR UIO
*/

View file

@ -40,7 +40,7 @@
#include <cryb/oath.h> #include <cryb/oath.h>
char * char *
oath_key_to_uri(const struct oath_key *key) oath_key_to_uri(const oath_key *key)
{ {
const char *hash; const char *hash;
char *tmp, *uri; char *tmp, *uri;

View file

@ -43,10 +43,10 @@ static const char *oath_mode_names[om_max] = {
/* /*
* Returns the enum value that corresponds to an OATH mode name * Returns the enum value that corresponds to an OATH mode name
*/ */
enum oath_mode oath_mode
oath_mode_value(const char *str) oath_mode_value(const char *str)
{ {
enum oath_mode om; oath_mode om;
for (om = 0; om < om_max; ++om) { for (om = 0; om < om_max; ++om) {
if (oath_mode_names[om] != NULL && if (oath_mode_names[om] != NULL &&
@ -61,7 +61,7 @@ oath_mode_value(const char *str)
* Returns the name of an OATH mode given its enum value * Returns the name of an OATH mode given its enum value
*/ */
const char * const char *
oath_mode_name(enum oath_mode om) oath_mode_name(oath_mode om)
{ {
if (om < om_max) if (om < om_max)

View file

@ -48,7 +48,7 @@ oath_totp(const uint8_t *K, size_t Klen, unsigned int Digit)
} }
unsigned int unsigned int
oath_totp_current(const struct oath_key *k) oath_totp_current(const oath_key *k)
{ {
unsigned int code; unsigned int code;
uint64_t seq; uint64_t seq;
@ -70,7 +70,7 @@ oath_totp_current(const struct oath_key *k)
* error occurred. * error occurred.
*/ */
int int
oath_totp_match(struct oath_key *k, unsigned int response, int window) oath_totp_match(oath_key *k, unsigned int response, int window)
{ {
unsigned int code; unsigned int code;
uint64_t seq; uint64_t seq;