4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * Copyright 2001,2002 Google, Inc.
19 * Copyright 2005,2006 TRI-D Systems, Inc.
29 #include <sys/types.h>
34 * Return some random bytes.
37 otp_get_random(char *rnd_data, size_t len)
39 size_t bytes_read = 0;
41 while (bytes_read < len) {
43 unsigned int bytes_left = len - bytes_read;
44 uint32_t r = lrad_rand();
46 n = sizeof(r) < bytes_left ? sizeof(r) : bytes_left;
47 (void) memcpy(rnd_data + bytes_read, &r, n);
53 * Return a random challenge.
54 * NOTE: This is really cryptocard-specific (automatic ASCII conversion
55 * and null termination).
58 otp_async_challenge(char challenge[OTP_MAX_CHALLENGE_LEN + 1], int len)
60 unsigned char rawchallenge[OTP_MAX_CHALLENGE_LEN];
63 otp_get_random(rawchallenge, len);
65 /* Convert the raw bytes to ASCII decimal. */
66 for (i = 0; i < len; ++i)
67 challenge[i] = '0' + rawchallenge[i] % 10;
68 challenge[len] = '\0';
71 /* ascii to hex; returns HEXlen on success or -1 on error */
73 otp_a2x(const char *s, unsigned char x[])
79 * We could just use sscanf, but we do this a lot, and have very
80 * specific needs, and it's easy to implement, so let's go for it!
82 for (i = 0; i < l / 2; ++i) {
86 /* extract 2 nibbles */
91 for (j = 0; j < 2; ++j) {
92 if ((n[j] >= '0' && n[j] <= '9') ||
93 (n[j] >= 'A' && n[j] <= 'F') ||
94 (n[j] >= 'a' && n[j] <= 'f'))
99 /* convert ASCII hex digits to numeric values */
103 if (n[0] > 'F' - '0')
104 n[0] -= 'a' - '9' - 1;
106 n[0] -= 'A' - '9' - 1;
109 if (n[1] > 'F' - '0')
110 n[1] -= 'a' - '9' - 1;
112 n[1] -= 'A' - '9' - 1;
115 /* store as octets */
118 } /* for (each octet) */
123 /* Character maps for generic hex and vendor specific decimal modes */
124 static const char otp_hex_conversion[] = "0123456789abcdef";
125 #if 0 /* just for reference */
126 static const char otp_cc_dec_conversion[] = "0123456789012345";
127 static const char otp_snk_dec_conversion[] = "0123456789222333";
128 static const char otp_sc_friendly_conversion[] = "0123456789ahcpef";
133 * Fills in s, which must point to at least len*2+1 bytes of space.
136 otp_x2a(const unsigned char *x, size_t len, char *s)
140 for (i = 0; i < len; ++i) {
143 n[0] = (x[i] >> 4) & 0x0f;
145 s[2 * i + 0] = otp_hex_conversion[n[0]];
146 s[2 * i + 1] = otp_hex_conversion[n[1]];
151 /* guaranteed initialization */
153 _otp_pthread_mutex_init(pthread_mutex_t *mutexp,
154 const pthread_mutexattr_t *attr, const char *caller)
158 if ((rc = pthread_mutex_init(mutexp, attr))) {
159 (void) radlog(L_ERR|L_CONS,
160 "rlm_otp: %s: pthread_mutex_init: %s", caller, strerror(rc));
165 /* guaranteed lock */
167 _otp_pthread_mutex_lock(pthread_mutex_t *mutexp, const char *caller)
171 if ((rc = pthread_mutex_lock(mutexp))) {
172 (void) radlog(L_ERR|L_CONS,
173 "rlm_otp: %s: pthread_mutex_lock: %s", caller, strerror(rc));
178 /* guaranteed trylock */
180 _otp_pthread_mutex_trylock(pthread_mutex_t *mutexp, const char *caller)
184 rc = pthread_mutex_trylock(mutexp);
185 if (rc && rc != EBUSY) {
186 (void) radlog(L_ERR|L_CONS,
187 "rlm_otp: %s: pthread_mutex_trylock: %s",
188 caller, strerror(rc));
195 /* guaranteed unlock */
197 _otp_pthread_mutex_unlock(pthread_mutex_t *mutexp, const char *caller)
201 if ((rc = pthread_mutex_unlock(mutexp))) {
202 (void) radlog(L_ERR|L_CONS,
203 "rlm_otp: %s: pthread_mutex_unlock: %s",
204 caller, strerror(rc));