From 4fa877aff1562bc4b912f0c8fcda7bd7de958b69 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Thu, 6 Sep 2018 22:10:24 -0700 Subject: [PATCH] Add totally untested OMAC1-AES, CT-KIP-PRF-AES Add totally untested implementations of the OMAC1-AES ("CMAC") and CT-KIP-PRF-AES pseudo-random function per relevant RFCs (but see also: mistakes in the RFC mentioned in #27). It compiles but that's about all I've tested. Broken: * Only supports tomcrypt * Untested!!! Re: #27 --- src/securid.c | 37 +++++++++++++++++++++++++++++++++++++ src/stc-tomcrypt.c | 38 ++++++++++++++++++++++++++++++++++++++ src/stoken-internal.h | 3 +++ 3 files changed, 78 insertions(+) diff --git a/src/securid.c b/src/securid.c index f5685e1..5d1c888 100644 --- a/src/securid.c +++ b/src/securid.c @@ -20,6 +20,7 @@ #include "config.h" +#include #include #include #include @@ -32,6 +33,8 @@ #include #include +#include + #include "securid.h" #include "sdtid.h" @@ -219,6 +222,40 @@ static void sha256_pbkdf2(const uint8_t *pass, int pass_len, } } +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +/* + * RFC 4758 D.2.2 + */ +static void ct_kip_prf_aes(const char *k, size_t klen, const char *s, + size_t slen, char *dst, size_t dstlen) +{ + const unsigned blen = AES_BLOCK_SIZE; + + size_t n, j, i; + + /* "2. ... Derived data too long" */ + assert(dstlen / blen <= UINT32_MAX); + + n = howmany(dstlen, blen); + j = dstlen % blen; + + for (i = 0; i < n; i++) { + size_t reslen; + uint32_t INT_i; + + if (i == n - 1 && j != 0) + reslen = j; + else + reslen = blen; + + INT_i = htonl(i + 1); + stc_omac1_aes(k, klen, &dst[i * blen], reslen, + s, slen, &INT_i, 4, NULL); + } +} + /******************************************************************** * V1/V2 token handling ********************************************************************/ diff --git a/src/stc-tomcrypt.c b/src/stc-tomcrypt.c index 424c736..9f05508 100644 --- a/src/stc-tomcrypt.c +++ b/src/stc-tomcrypt.c @@ -121,6 +121,44 @@ void stc_aes256_cbc_encrypt(const uint8_t *key, const uint8_t *in, int in_len, rijndael_done(&skey); } +void stc_omac1_aes(const void *key, size_t klen, void *result, size_t reslen, + ...) +{ + unsigned long olen; + omac_state md; + int aes_idx; + va_list ap; + int rc; + + aes_idx = find_cipher("aes"); + if (aes_idx == -1) + aes_idx = find_cipher("rijndael"); + if (aes_idx == -1) + abort(); + + rc = omac_init(&md, aes_idx, key, klen); + assert(rc == CRYPT_OK); + + va_start(ap, reslen); + while (1) { + const void *nextin = va_arg(ap, const void *); + size_t inlen; + + if (nextin == NULL) + break; + inlen = va_arg(ap, size_t); + + rc = omac_process(&md, nextin, inlen); + assert(rc == CRYPT_OK); + } + va_end(ap); + + olen = reslen; + rc = omac_done(&md, result, &olen); + assert(rc == CRYPT_OK); + assert(olen == reslen); +} + void stc_sha1_hash(uint8_t *out, ...) { va_list ap; diff --git a/src/stoken-internal.h b/src/stoken-internal.h index f7a69c0..d95ae33 100644 --- a/src/stoken-internal.h +++ b/src/stoken-internal.h @@ -21,6 +21,7 @@ #ifndef __STOKEN_INTERNAL_H__ #define __STOKEN_INTERNAL_H__ +#include #include #include "stoken.h" @@ -101,6 +102,8 @@ void stc_aes256_cbc_decrypt(const uint8_t *key, const uint8_t *in, int in_len, const uint8_t *iv, uint8_t *out); void stc_aes256_cbc_encrypt(const uint8_t *key, const uint8_t *in, int in_len, const uint8_t *iv, uint8_t *out); +void stc_omac1_aes(const void *key, size_t klen, void *result, size_t reslen, + ...); void stc_sha1_hash(uint8_t *out, ...); void stc_sha256_hash(uint8_t *out, ...); int stc_b64_encode(const uint8_t *in, unsigned long len,