From b997dc89a55142f42c8da77b3b35ae5a7f3a072c Mon Sep 17 00:00:00 2001 From: "David M. Syzdek" Date: Thu, 12 Jan 2023 02:59:18 -0900 Subject: libotputil: adding otputil_skey_code() and otputil_skey_str() --- include/otputil.h | 17 +++++++++ lib/libotputil/libotputil.sym | 2 + lib/libotputil/lrfc1760-skey.c | 87 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/include/otputil.h b/include/otputil.h index 13420fc..b6d6112 100644 --- a/include/otputil.h +++ b/include/otputil.h @@ -173,6 +173,8 @@ #define OTPUTIL_OTP_SEED_MIN_LEN 1 #define OTPUTIL_OTP_SEED_MAX_LEN 16 +#define OTPUTIL_SKEY_PASS_MAX_LEN 127 + ///////////////// // // @@ -397,6 +399,13 @@ otputil_otp_str( //----------------// #pragma mark S/KEY functions (RFC 1760) +_OTPUTIL_F int +otputil_skey_code( + const char * skey_pass, + int skey_seq, + uint64_t * skey_resultp ); + + _OTPUTIL_F int otputil_skey_dict_value( const char * word ); @@ -407,6 +416,14 @@ otputil_skey_dict_word( int value ); +_OTPUTIL_F char * +otputil_skey_str( + const char * skey_pass, + int skey_seq, + char * dst, + size_t dstlen ); + + //---------------// // TOTP functions // //---------------// diff --git a/lib/libotputil/libotputil.sym b/lib/libotputil/libotputil.sym index c3faedb..cf898f6 100644 --- a/lib/libotputil/libotputil.sym +++ b/lib/libotputil/libotputil.sym @@ -93,8 +93,10 @@ otputil_otp_encode_len otputil_otp_str # # S/KEY functions (RFC 1760) +otputil_skey_code otputil_skey_dict_value otputil_skey_dict_word +otputil_skey_str # # TOTP functions (RFC 6238) otputil_totp_code diff --git a/lib/libotputil/lrfc1760-skey.c b/lib/libotputil/lrfc1760-skey.c index 62e5d5e..1853455 100644 --- a/lib/libotputil/lrfc1760-skey.c +++ b/lib/libotputil/lrfc1760-skey.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include "lrfc1760-skey-dict.h" @@ -136,4 +138,89 @@ otputil_skey_dict_word( } +//---------------// +// OTP functions // +//---------------// +#pragma mark OTP functions + +int +otputil_skey_code( + const char * skey_pass, + int skey_seq, + uint64_t * skey_resultp ) +{ + unsigned char secret[OTPUTIL_SKEY_PASS_MAX_LEN+1]; + const EVP_MD * evp_md; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned md_len; + unsigned secret_len; + unsigned u; + int pos; + + assert(skey_pass != NULL); + + // generate secret + secret_len = (int)strlen(skey_pass); + if (secret_len > OTPUTIL_SKEY_PASS_MAX_LEN) + return(-1); + bindle_strlcpy((char *)secret, skey_pass, sizeof(secret)); + + // check otp_hash + evp_md = EVP_md4(); + + // generate hashes + for(pos = 0; (pos <= skey_seq); pos++) + { + md_len = sizeof(md); + if (!(EVP_Digest(secret, secret_len, md, &md_len, evp_md, NULL))) + return(-1); + for(u = 0; (u < 8); u++) + md[u] ^= md[u+8]; + memcpy(secret, md, 8); + secret_len = 8; + }; + + *skey_resultp = ((uint64_t)secret[0] << 56) | ((uint64_t)secret[1] << 48) + | ((uint64_t)secret[2] << 40) | ((uint64_t)secret[3] << 32) + | ((uint64_t)secret[4] << 24) | ((uint64_t)secret[5] << 16) + | ((uint64_t)secret[6] << 8) | ((uint64_t)secret[7] << 0); + + return(0); +} + + +char * +otputil_skey_str( + const char * skey_pass, + int skey_seq, + char * dst, + size_t dstlen ) +{ + uint64_t val; + otputil_bv_t res; + uint8_t bv_val[8]; + static char buff[32]; + + dstlen = ((dst)) ? dstlen : sizeof(buff); + dst = ((dst)) ? dst : buff; + res.bv_val = bv_val; + res.bv_len = sizeof(bv_val); + + if (otputil_skey_code(skey_pass, skey_seq, &val) == -1) + return(NULL); + + bv_val[0] = (val >> 56) & 0xff; + bv_val[1] = (val >> 48) & 0xff; + bv_val[2] = (val >> 40) & 0xff; + bv_val[3] = (val >> 32) & 0xff; + bv_val[4] = (val >> 24) & 0xff; + bv_val[5] = (val >> 16) & 0xff; + bv_val[6] = (val >> 8) & 0xff; + bv_val[7] = (val >> 0) & 0xff; + otputil_otp_encode(&res, dst, dstlen, OTPUTIL_ENC_SIXWORD); + + return(dst); +} + + /* end of source file */ -- cgit v1.2.3