Skip to content

Commit

Permalink
Add totally untested OMAC1-AES, CT-KIP-PRF-{AES,SHA256}
Browse files Browse the repository at this point in the history
Add totally untested implementations of the OMAC1-AES ("CMAC") and
CT-KIP-PRF-* family of pseudo-random functions per relevant RFCs.  It
compiles but that's about all I've tested.

Broken:
* Only supports tomcrypt
* Untested!!!
* Mallocs in PRF-SHA256 variant to work around missing iterative
  sha256-hmac.  Could add iterative hmac instead and skip malloc.

Re: stoken-dev#27
  • Loading branch information
cemeyer committed Sep 7, 2018
1 parent af93411 commit c353577
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/securid.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "config.h"

#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdint.h>
Expand All @@ -32,6 +33,8 @@
#include <sys/types.h>
#include <unistd.h>

#include <arpa/inet.h>

#include "securid.h"
#include "sdtid.h"

Expand Down Expand Up @@ -219,6 +222,88 @@ 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,
&INT_i, 4, s, slen, NULL);
}
}

/*
* RFC 4758 D.3.
*/
static void ct_kip_prf_sha256(const void *k, size_t klen, const char *s,
size_t slen, char *dst, size_t dstlen)
{
const unsigned blen = SHA256_HASH_SIZE;

void *out;
char tmp_hash[SHA256_HASH_SIZE], *maccontents;
size_t n, j, i;

/* "2. ... Derived data too long" */
assert(dstlen / blen <= UINT32_MAX);

/* crappy workaround for missing iterative sha256_hmac */
maccontents = malloc(slen + 4);
assert(maccontents != NULL);
memcpy(maccontents + 4, s, slen);

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) {
out = tmp_hash;
reslen = j;
} else {
reslen = blen;
out = &dst[i * blen];
}

INT_i = htonl(i + 1);
memcpy(maccontents, &INT_i, 4);
sha256_hmac(k, klen, (void *)maccontents, slen + 4, out);

if (out == tmp_hash) {
memcpy(&dst[i * blen], out, j);
explicit_bzero(tmp_hash, sizeof(tmp_hash));
}
}

free(maccontents);
}

/********************************************************************
* V1/V2 token handling
********************************************************************/
Expand Down
38 changes: 38 additions & 0 deletions src/stc-tomcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/stoken-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef __STOKEN_INTERNAL_H__
#define __STOKEN_INTERNAL_H__

#include <stdarg.h>
#include <stdint.h>
#include "stoken.h"

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit c353577

Please sign in to comment.