/* * $Id: 8722075f1b784279cc7768481359fb70863544a7 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2001,2002 Google, Inc. * Copyright 2005,2006 TRI-D Systems, Inc. */ RCSID("$Id: 8722075f1b784279cc7768481359fb70863544a7 $") #include "extern.h" #include #include #include #include #include /** Generate some random bytes * * @param rnd_data Buffer to write bytes to. * @param len Number of bytes to write. */ void otp_get_random(uint8_t *rnd_data, size_t len) { size_t bytes_read = 0; size_t bytes_left; int n; while (bytes_read < len) { bytes_left = len - bytes_read; uint32_t r = fr_rand(); n = sizeof(r) < bytes_left ? sizeof(r) : bytes_left; memcpy(rnd_data + bytes_read, &r, n); bytes_read += n; } } /** Generate a random challenge (ascii chars 0-9) * * @note This is really cryptocard-specific (automatic ASCII conversion * @note and null termination). * * @param[out] challenge Buffer to write random string to. * @param[in] len Number of random bytes to write to buffer. */ void otp_async_challenge(char challenge[OTP_MAX_CHALLENGE_LEN + 1], size_t len) { uint8_t rawchallenge[OTP_MAX_CHALLENGE_LEN]; unsigned int i; otp_get_random(rawchallenge, len); /* Convert the raw bytes to ASCII decimal. */ for (i = 0; i < len; ++i) { challenge[i] = '0' + rawchallenge[i] % 10; } challenge[len] = '\0'; } /** Guaranteed initialization * */ void _otp_pthread_mutex_init(pthread_mutex_t *mutexp, pthread_mutexattr_t const *attr, char const *caller) { int rc; rc = pthread_mutex_init(mutexp, attr); if (rc) { ERROR("rlm_otp: %s: pthread_mutex_init: %s", caller, fr_syserror(rc)); exit(1); } } /** Guaranteed lock * */ void _otp_pthread_mutex_lock(pthread_mutex_t *mutexp, char const *caller) { int rc; rc = pthread_mutex_lock(mutexp); if (rc) { ERROR("rlm_otp: %s: pthread_mutex_lock: %s", caller, fr_syserror(rc)); exit(1); } } /** Guaranteed trylock * */ int _otp_pthread_mutex_trylock(pthread_mutex_t *mutexp, char const *caller) { int rc; rc = pthread_mutex_trylock(mutexp); if (rc && rc != EBUSY) { ERROR("rlm_otp: %s: pthread_mutex_trylock: %s", caller, fr_syserror(rc)); exit(1); } return rc; } /** Guaranteed unlock * */ void _otp_pthread_mutex_unlock(pthread_mutex_t *mutexp, char const *caller) { int rc; rc = pthread_mutex_unlock(mutexp); if (rc) { ERROR("rlm_otp: %s: pthread_mutex_unlock: %s", caller, fr_syserror(rc)); exit(1); } }