merged EAP framework from branch into trunk
includes a lot of other modifications
This commit is contained in:
@@ -12,6 +12,7 @@ asn1/pem.c asn1/pem.h \
|
||||
asn1/ttodata.c asn1/ttodata.h \
|
||||
crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \
|
||||
crypto/rsa/rsa_public_key.h crypto/rsa/rsa_public_key.c \
|
||||
crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \
|
||||
crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \
|
||||
crypto/prfs/prf.c crypto/prfs/prf.h \
|
||||
crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \
|
||||
|
||||
+148
-36
@@ -35,13 +35,22 @@ chunk_t chunk_empty = { NULL, 0 };
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
chunk_t chunk_clone(chunk_t chunk)
|
||||
chunk_t chunk_create(u_char *ptr, size_t len)
|
||||
{
|
||||
chunk_t chunk = {ptr, len};
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk)
|
||||
{
|
||||
chunk_t clone = chunk_empty;
|
||||
|
||||
if (chunk.ptr && chunk.len > 0)
|
||||
{
|
||||
clone.ptr = malloc(chunk.len);
|
||||
clone.ptr = ptr;
|
||||
clone.len = chunk.len;
|
||||
memcpy(clone.ptr, chunk.ptr, chunk.len);
|
||||
}
|
||||
@@ -52,51 +61,151 @@ chunk_t chunk_clone(chunk_t chunk)
|
||||
/**
|
||||
* Decribed in header.
|
||||
*/
|
||||
chunk_t chunk_cat(const char* mode, ...)
|
||||
size_t chunk_length(const char* mode, ...)
|
||||
{
|
||||
chunk_t construct;
|
||||
va_list chunks;
|
||||
u_char *pos;
|
||||
int i;
|
||||
int count = strlen(mode);
|
||||
|
||||
/* sum up lengths of individual chunks */
|
||||
size_t length = 0;
|
||||
|
||||
va_start(chunks, mode);
|
||||
construct.len = 0;
|
||||
for (i = 0; i < count; i++)
|
||||
while (TRUE)
|
||||
{
|
||||
chunk_t ch = va_arg(chunks, chunk_t);
|
||||
construct.len += ch.len;
|
||||
}
|
||||
va_end(chunks);
|
||||
|
||||
/* allocate needed memory for construct */
|
||||
construct.ptr = malloc(construct.len);
|
||||
pos = construct.ptr;
|
||||
|
||||
/* copy or move the chunks */
|
||||
va_start(chunks, mode);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
chunk_t ch = va_arg(chunks, chunk_t);
|
||||
switch (*mode++)
|
||||
{
|
||||
case 'm':
|
||||
memcpy(pos, ch.ptr, ch.len);
|
||||
pos += ch.len;
|
||||
free(ch.ptr);
|
||||
break;
|
||||
case 'c':
|
||||
{
|
||||
chunk_t ch = va_arg(chunks, chunk_t);
|
||||
length += ch.len;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
memcpy(pos, ch.ptr, ch.len);
|
||||
pos += ch.len;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(chunks);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decribed in header.
|
||||
*/
|
||||
chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...)
|
||||
{
|
||||
va_list chunks;
|
||||
chunk_t construct = chunk_create(ptr, 0);
|
||||
|
||||
va_start(chunks, mode);
|
||||
while (TRUE)
|
||||
{
|
||||
bool free_chunk = FALSE;
|
||||
switch (*mode++)
|
||||
{
|
||||
case 'm':
|
||||
{
|
||||
free_chunk = TRUE;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
chunk_t ch = va_arg(chunks, chunk_t);
|
||||
memcpy(ptr, ch.ptr, ch.len);
|
||||
ptr += ch.len;
|
||||
construct.len += ch.len;
|
||||
if (free_chunk)
|
||||
{
|
||||
free(ch.ptr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(chunks);
|
||||
|
||||
return construct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decribed in header.
|
||||
*/
|
||||
void chunk_split(chunk_t chunk, const char *mode, ...)
|
||||
{
|
||||
va_list chunks;
|
||||
size_t len;
|
||||
chunk_t *ch;
|
||||
|
||||
va_start(chunks, mode);
|
||||
while (TRUE)
|
||||
{
|
||||
if (*mode == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
len = va_arg(chunks, size_t);
|
||||
ch = va_arg(chunks, chunk_t*);
|
||||
/* a null chunk means skip len bytes */
|
||||
if (ch == NULL)
|
||||
{
|
||||
chunk = chunk_skip(chunk, len);
|
||||
continue;
|
||||
}
|
||||
switch (*mode++)
|
||||
{
|
||||
case 'm':
|
||||
{
|
||||
ch->len = min(chunk.len, len);
|
||||
if (ch->len)
|
||||
{
|
||||
ch->ptr = chunk.ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch->ptr = NULL;
|
||||
}
|
||||
chunk = chunk_skip(chunk, ch->len);
|
||||
continue;
|
||||
}
|
||||
case 'a':
|
||||
{
|
||||
ch->len = min(chunk.len, len);
|
||||
if (ch->len)
|
||||
{
|
||||
ch->ptr = malloc(ch->len);
|
||||
memcpy(ch->ptr, chunk.ptr, ch->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ch->ptr = NULL;
|
||||
}
|
||||
chunk = chunk_skip(chunk, ch->len);
|
||||
continue;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
ch->len = min(ch->len, chunk.len);
|
||||
ch->len = min(ch->len, len);
|
||||
if (ch->len)
|
||||
{
|
||||
memcpy(ch->ptr, chunk.ptr, ch->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ch->ptr = NULL;
|
||||
}
|
||||
chunk = chunk_skip(chunk, ch->len);
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(chunks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
@@ -110,12 +219,15 @@ void chunk_free(chunk_t *chunk)
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
chunk_t chunk_alloc(size_t bytes)
|
||||
chunk_t chunk_skip(chunk_t chunk, size_t bytes)
|
||||
{
|
||||
chunk_t new_chunk;
|
||||
new_chunk.ptr = malloc(bytes);
|
||||
new_chunk.len = bytes;
|
||||
return new_chunk;
|
||||
if (chunk.len > bytes)
|
||||
{
|
||||
chunk.ptr += bytes;
|
||||
chunk.len -= bytes;
|
||||
return chunk;
|
||||
}
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+60
-10
@@ -47,21 +47,36 @@ struct chunk_t {
|
||||
extern chunk_t chunk_empty;
|
||||
|
||||
/**
|
||||
* Initialize a chunk to point to a static(!) buffer
|
||||
* Create a new chunk pointing to "ptr" with length "len"
|
||||
*/
|
||||
#define chunk_from_buf(str) { str, sizeof(str) }
|
||||
chunk_t chunk_create(u_char *ptr, size_t len);
|
||||
|
||||
/**
|
||||
* Clone chunk contents in a newly allocated chunk
|
||||
* Create a clone of a chunk pointing to "ptr"
|
||||
*/
|
||||
chunk_t chunk_clone(chunk_t chunk);
|
||||
chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk);
|
||||
|
||||
/**
|
||||
* Allocate a chunk from concatenation of other chunks.
|
||||
* mode is a string 'm' and 'c, 'm' means move chunk,
|
||||
* 'c' means copy chunk.
|
||||
* Calculate length of multiple chunks
|
||||
*/
|
||||
chunk_t chunk_cat(const char* mode, ...);
|
||||
size_t chunk_length(const char *mode, ...);
|
||||
|
||||
/**
|
||||
* Concatenate chunks into a chunk pointing to "ptr",
|
||||
* "mode" is a string of "c" (copy) and "m" (move), which says
|
||||
* how to handle to chunks in "..."
|
||||
*/
|
||||
chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...);
|
||||
|
||||
/**
|
||||
* Split up a chunk into parts, "mode" is a string of "a" (alloc),
|
||||
* "c" (copy) and "m" (move). Each letter say for the corresponding chunk if
|
||||
* it should get allocated on heap, copied into existing chunk, or the chunk
|
||||
* should point into "chunk". The length of each part is an argument before
|
||||
* each target chunk. E.g.:
|
||||
* chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d);
|
||||
*/
|
||||
void chunk_split(chunk_t chunk, const char *mode, ...);
|
||||
|
||||
/**
|
||||
* Free contents of a chunk
|
||||
@@ -69,9 +84,44 @@ chunk_t chunk_cat(const char* mode, ...);
|
||||
void chunk_free(chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* Allocate a chunk
|
||||
* Initialize a chunk to point to buffer inspectable by sizeof()
|
||||
*/
|
||||
chunk_t chunk_alloc(size_t bytes);
|
||||
#define chunk_from_buf(str) { str, sizeof(str) }
|
||||
|
||||
/**
|
||||
* Allocate a chunk on the heap
|
||||
*/
|
||||
#define chunk_alloc(bytes) chunk_create(malloc(bytes), bytes)
|
||||
|
||||
/**
|
||||
* Allocate a chunk on the stack
|
||||
*/
|
||||
#define chunk_alloca(bytes) chunk_create(alloca(bytes), bytes)
|
||||
|
||||
/**
|
||||
* Clone a chunk on heap
|
||||
*/
|
||||
#define chunk_clone(chunk) chunk_create_clone(malloc(chunk.len), chunk)
|
||||
|
||||
/**
|
||||
* Clone a chunk on stack
|
||||
*/
|
||||
#define chunk_clonea(chunk) chunk_create_clone(alloca(chunk.len), chunk)
|
||||
|
||||
/**
|
||||
* Concatenate chunks into a chunk on heap
|
||||
*/
|
||||
#define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Concatenate chunks into a chunk on stack
|
||||
*/
|
||||
#define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Skip n bytes in chunk (forward pointer, shorten length)
|
||||
*/
|
||||
chunk_t chunk_skip(chunk_t chunk, size_t bytes);
|
||||
|
||||
/**
|
||||
* Compare two chunks for equality,
|
||||
|
||||
@@ -122,10 +122,24 @@ struct hasher_t {
|
||||
*/
|
||||
void (*reset) (hasher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the state of the hasher.
|
||||
*
|
||||
* A hasher stores internal state information. This state may be
|
||||
* manipulated to include a "seed" into the hashing operation. It used by
|
||||
* some exotic protocols (such as AKA).
|
||||
* The data pointed by chunk may be manipulated, but not replaced nor freed.
|
||||
* This is more a hack than a feature. The hasher's state may be byte
|
||||
* order dependant; use with care.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
chunk_t (*get_state) (hasher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a hasher object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (hasher_t *this);
|
||||
};
|
||||
|
||||
@@ -363,6 +363,19 @@ static void reset(private_md5_hasher_t *this)
|
||||
this->count[1] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.get_state
|
||||
*/
|
||||
static chunk_t get_state(private_md5_hasher_t *this)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
chunk.ptr = (u_char*)&this->state[0];
|
||||
chunk.len = sizeof(this->state);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.destroy.
|
||||
*/
|
||||
@@ -382,6 +395,7 @@ md5_hasher_t *md5_hasher_create(void)
|
||||
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
|
||||
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
|
||||
this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
|
||||
this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
|
||||
this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
|
||||
|
||||
/* initialize */
|
||||
|
||||
@@ -223,7 +223,7 @@ static size_t get_hash_size(private_sha1_hasher_t *this)
|
||||
{
|
||||
return HASH_SIZE_SHA1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.reset.
|
||||
*/
|
||||
@@ -237,6 +237,20 @@ static void reset(private_sha1_hasher_t *this)
|
||||
this->count[0] = 0;
|
||||
this->count[1] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.get_state
|
||||
*/
|
||||
static chunk_t get_state(private_sha1_hasher_t *this)
|
||||
{
|
||||
chunk_t chunk;
|
||||
|
||||
chunk.ptr = (u_char*)&this->state[0];
|
||||
chunk.len = sizeof(this->state);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.destroy.
|
||||
*/
|
||||
@@ -256,6 +270,7 @@ sha1_hasher_t *sha1_hasher_create(void)
|
||||
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
|
||||
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
|
||||
this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
|
||||
this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
|
||||
this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
|
||||
|
||||
/* initialize */
|
||||
|
||||
@@ -586,6 +586,38 @@ static void reset512(private_sha512_hasher_t *ctx)
|
||||
ctx->sha_bufCnt = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.get_state for SHA256
|
||||
*/
|
||||
static chunk_t get_state256(private_sha256_hasher_t *ctx)
|
||||
{
|
||||
chunk_t chunk;
|
||||
chunk.ptr = (u_char*)&ctx->sha_H[0];
|
||||
chunk.len = HASH_SIZE_SHA256;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.get_state for SHA384
|
||||
*/
|
||||
static chunk_t get_state384(private_sha512_hasher_t *ctx)
|
||||
{
|
||||
chunk_t chunk;
|
||||
chunk.ptr = (u_char*)&ctx->sha_H[0];
|
||||
chunk.len = HASH_SIZE_SHA384;
|
||||
return chunk;
|
||||
}
|
||||
/**
|
||||
* Implementation of hasher_t.get_state for SHA512
|
||||
*/
|
||||
static chunk_t get_state512(private_sha512_hasher_t *ctx)
|
||||
{
|
||||
chunk_t chunk;
|
||||
chunk.ptr = (u_char*)&ctx->sha_H[0];
|
||||
chunk.len = HASH_SIZE_SHA512;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hasher_t.destroy.
|
||||
*/
|
||||
@@ -606,6 +638,7 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
|
||||
case HASH_SHA256:
|
||||
this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
|
||||
this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
|
||||
this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state256;
|
||||
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
|
||||
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
|
||||
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
|
||||
@@ -614,6 +647,7 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
|
||||
/* uses SHA512 data structure */
|
||||
this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
|
||||
this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
|
||||
this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state384;
|
||||
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
|
||||
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
|
||||
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
|
||||
@@ -621,6 +655,7 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
|
||||
case HASH_SHA512:
|
||||
this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
|
||||
this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
|
||||
this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state512;
|
||||
this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
|
||||
this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
|
||||
this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/**
|
||||
* @file fips_prf.c
|
||||
*
|
||||
* @brief Implementation for fips_prf_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "fips_prf.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct private_fips_prf_t private_fips_prf_t;
|
||||
|
||||
/**
|
||||
* Private data of a fips_prf_t object.
|
||||
*/
|
||||
struct private_fips_prf_t {
|
||||
/**
|
||||
* Public fips_prf_t interface.
|
||||
*/
|
||||
fips_prf_t public;
|
||||
|
||||
/**
|
||||
* key of prf function, "b" long
|
||||
*/
|
||||
u_int8_t *key;
|
||||
|
||||
/**
|
||||
* size of "b" in bytes
|
||||
*/
|
||||
size_t b;
|
||||
|
||||
/**
|
||||
* G function, either SHA1 or DES
|
||||
*/
|
||||
void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]);
|
||||
};
|
||||
|
||||
/**
|
||||
* t used in G(), equals to initial SHA1 value
|
||||
*/
|
||||
static u_int8_t t[] = {
|
||||
0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
|
||||
0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
|
||||
};
|
||||
|
||||
/**
|
||||
* sum = (a + b) mod 2 ^ (length * 8)
|
||||
*/
|
||||
static void add_mod(size_t length, u_int8_t a[], u_int8_t b[], u_int8_t sum[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = length - 1; i >= 0; i--)
|
||||
{
|
||||
u_int32_t tmp;
|
||||
int c = 0;
|
||||
|
||||
tmp = a[i] + b[i] + c;
|
||||
sum[i] = 0xff & tmp;
|
||||
c = tmp >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate "chunk mod 2^(length*8)" and save it into buffer
|
||||
*/
|
||||
static void chunk_mod(size_t length, chunk_t chunk, u_int8_t buffer[])
|
||||
{
|
||||
if (chunk.len < length)
|
||||
{
|
||||
/* apply seed as least significant bits, others are zero */
|
||||
memset(buffer, 0, length - chunk.len);
|
||||
memcpy(buffer + length - chunk.len, chunk.ptr, chunk.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use least significant bytes from seed, as we use mod 2^b */
|
||||
memcpy(buffer, chunk.ptr + chunk.len - length, length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of prf_t.get_bytes.
|
||||
*
|
||||
* Test vector:
|
||||
*
|
||||
* key:
|
||||
* 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
|
||||
* 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
|
||||
* 0xeb, 0x5a, 0x38, 0xb6
|
||||
*
|
||||
* seed:
|
||||
* 0x00
|
||||
*
|
||||
* result:
|
||||
* 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
|
||||
* 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
|
||||
* 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
|
||||
* 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
|
||||
* 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
|
||||
*/
|
||||
static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
|
||||
{
|
||||
int i;
|
||||
u_int8_t xval[this->b];
|
||||
u_int8_t xseed[this->b];
|
||||
u_int8_t *xkey = this->key;
|
||||
u_int8_t one[this->b];
|
||||
chunk_t xval_chunk = chunk_from_buf(xval);
|
||||
|
||||
memset(one, 0, this->b);
|
||||
one[this->b - 1] = 0x01;
|
||||
|
||||
/* 3.1 */
|
||||
chunk_mod(this->b, seed, xseed);
|
||||
|
||||
/* 3.2 */
|
||||
for (i = 0; i < 2; i++) /* twice */
|
||||
{
|
||||
/* a. XVAL = (XKEY + XSEED j) mod 2^b */
|
||||
add_mod(this->b, xkey, xseed, xval);
|
||||
DBG3("XVAL %b", xval, this->b);
|
||||
/* b. wi = G(t, XVAL ) */
|
||||
this->g(t, xval_chunk, &w[i * this->b]);
|
||||
DBG3("w[%d] %b", i, &w[i * this->b], this->b);
|
||||
/* c. XKEY = (1 + XKEY + wi) mod 2b */
|
||||
add_mod(this->b, xkey, one, xkey);
|
||||
add_mod(this->b, xkey, &w[i * this->b], xkey);
|
||||
DBG3("XKEY %b", xkey, this->b);
|
||||
}
|
||||
|
||||
/* 3.3 done already, mod q not used */
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of prf_t.get_block_size.
|
||||
*/
|
||||
static size_t get_block_size(private_fips_prf_t *this)
|
||||
{
|
||||
return 2 * this->b;
|
||||
}
|
||||
/**
|
||||
* Implementation of prf_t.allocate_bytes.
|
||||
*/
|
||||
static void allocate_bytes(private_fips_prf_t *this, chunk_t seed, chunk_t *chunk)
|
||||
{
|
||||
*chunk = chunk_alloc(get_block_size(this));
|
||||
get_bytes(this, seed, chunk->ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of prf_t.get_key_size.
|
||||
*/
|
||||
static size_t get_key_size(private_fips_prf_t *this)
|
||||
{
|
||||
return this->b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of prf_t.set_key.
|
||||
*/
|
||||
static void set_key(private_fips_prf_t *this, chunk_t key)
|
||||
{
|
||||
/* save key as "key mod 2^b" */
|
||||
chunk_mod(this->b, key, this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the G() function based on SHA1
|
||||
*/
|
||||
void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
|
||||
{
|
||||
hasher_t *hasher;
|
||||
u_int8_t buf[64];
|
||||
chunk_t state_chunk;
|
||||
u_int32_t *state, *iv, *hash;
|
||||
|
||||
if (c.len < sizeof(buf))
|
||||
{
|
||||
/* pad c with zeros */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, c.ptr, c.len);
|
||||
c.ptr = buf;
|
||||
c.len = sizeof(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not more than 512 bits can be G()-ed */
|
||||
c.len = sizeof(buf);
|
||||
}
|
||||
|
||||
/* our SHA1 hasher's state is 32-Bit integers in host order. We must
|
||||
* convert them */
|
||||
hasher = hasher_create(HASH_SHA1);
|
||||
state_chunk = hasher->get_state(hasher);
|
||||
state = (u_int32_t*)state_chunk.ptr;
|
||||
iv = (u_int32_t*)t;
|
||||
hash = (u_int32_t*)res;
|
||||
state[0] = htonl(iv[0]);
|
||||
state[1] = htonl(iv[1]);
|
||||
state[2] = htonl(iv[2]);
|
||||
state[3] = htonl(iv[3]);
|
||||
hasher->get_hash(hasher, c, NULL);
|
||||
hash[0] = htonl(state[0]);
|
||||
hash[1] = htonl(state[1]);
|
||||
hash[2] = htonl(state[2]);
|
||||
hash[3] = htonl(state[3]);
|
||||
hash[4] = htonl(state[4]);
|
||||
hasher->destroy(hasher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of prf_t.destroy.
|
||||
*/
|
||||
static void destroy(private_fips_prf_t *this)
|
||||
{
|
||||
free(this->key);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
|
||||
{
|
||||
private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
|
||||
|
||||
this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
|
||||
this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
|
||||
this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
|
||||
this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
|
||||
this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
|
||||
this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
|
||||
|
||||
this->g = g;
|
||||
this->b = b;
|
||||
this->key = malloc(b);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file fips_prf.h
|
||||
*
|
||||
* @brief Interface of fips_prf_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FIPS_PRF_H_
|
||||
#define FIPS_PRF_H_
|
||||
|
||||
typedef struct fips_prf_t fips_prf_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
/**
|
||||
* @brief Implementation of prf_t using the FIPS 186-2-change1 standard.
|
||||
*
|
||||
* FIPS defines a "General Purpose Random Number Generator" (Revised
|
||||
* Algorithm for Computing m values of x (Appendix 3.1 of FIPS 186-2)). This
|
||||
* implementation is not intended for private key generation and therefore does
|
||||
* not include the "mod q" operation (see FIPS 186-2-change1 p74).
|
||||
* The FIPS PRF is stateful; the key changes every time when bytes are acquired.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - fips_prf_create()
|
||||
* - prf_create() using one of the FIPS algorithms
|
||||
*
|
||||
* @ingroup prfs
|
||||
*/
|
||||
struct fips_prf_t {
|
||||
|
||||
/**
|
||||
* Generic prf_t interface for this fips_prf_t class.
|
||||
*/
|
||||
prf_t prf_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a new fips_prf_t object.
|
||||
*
|
||||
* FIPS 186-2 defines G() functions used in the PRF function. It can
|
||||
* be implemented either based on SHA1 or DES.
|
||||
*
|
||||
* @param b size of b (in bytes, not bits)
|
||||
* @param g G() function to use (e.g. g_sha1)
|
||||
* @return
|
||||
* - fips_prf_t object
|
||||
* - NULL if b invalid not supported
|
||||
*
|
||||
* @ingroup prfs
|
||||
*/
|
||||
fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]));
|
||||
|
||||
/**
|
||||
* @brief Implementation of the G() function based on SHA1.
|
||||
*
|
||||
* @param t initialization vector for SHA1 hasher, 20 bytes long
|
||||
* @param c value to hash, not longer than 512 bit
|
||||
* @param res result of G(), requries 20 bytes
|
||||
*/
|
||||
void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]);
|
||||
|
||||
#endif /* FIPS_PRF_H_ */
|
||||
@@ -26,10 +26,13 @@
|
||||
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/prfs/hmac_prf.h>
|
||||
#include <crypto/prfs/fips_prf.h>
|
||||
|
||||
ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_UNDEFINED,
|
||||
"PRF_UNDEFINED");
|
||||
ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CBC, PRF_UNDEFINED,
|
||||
ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
|
||||
"PRF_UNDEFINED",
|
||||
"PRF_FIPS_SHA1_160",
|
||||
"PRF_FIPS_DES");
|
||||
ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CBC, PRF_FIPS_DES,
|
||||
"PRF_HMAC_MD5",
|
||||
"PRF_HMAC_SHA1",
|
||||
"PRF_HMAC_TIGER",
|
||||
@@ -44,13 +47,12 @@ prf_t *prf_create(pseudo_random_function_t pseudo_random_function)
|
||||
switch (pseudo_random_function)
|
||||
{
|
||||
case PRF_HMAC_SHA1:
|
||||
{
|
||||
return (prf_t*)hmac_prf_create(HASH_SHA1);
|
||||
}
|
||||
case PRF_HMAC_MD5:
|
||||
{
|
||||
return (prf_t*)hmac_prf_create(HASH_MD5);
|
||||
}
|
||||
case PRF_FIPS_SHA1_160:
|
||||
return (prf_t*)fips_prf_create(20, g_sha1);
|
||||
case PRF_FIPS_DES:
|
||||
case PRF_HMAC_TIGER:
|
||||
case PRF_AES128_CBC:
|
||||
default:
|
||||
|
||||
@@ -31,11 +31,10 @@ typedef struct prf_t prf_t;
|
||||
|
||||
/**
|
||||
* @brief Pseudo random function, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* Currently only the following algorithms are implemented:
|
||||
* - PRF_HMAC_MD5
|
||||
* - PRF_HMAC_SHA1
|
||||
*
|
||||
*
|
||||
* PRF algorithms not defined in IKEv2 are allocated in "private use"
|
||||
* space.
|
||||
*
|
||||
* @ingroup prfs
|
||||
*/
|
||||
enum pseudo_random_function_t {
|
||||
@@ -46,6 +45,10 @@ enum pseudo_random_function_t {
|
||||
PRF_HMAC_SHA1 = 2,
|
||||
PRF_HMAC_TIGER = 3,
|
||||
PRF_AES128_CBC = 4,
|
||||
/** Implemented via fips_prf_t, other output sizes would be possible */
|
||||
PRF_FIPS_SHA1_160 = 1025,
|
||||
/** Could be implemented via fips_prf_t, uses fixed output size of 160bit */
|
||||
PRF_FIPS_DES = 1026,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -93,6 +96,9 @@ struct prf_t {
|
||||
|
||||
/**
|
||||
* @brief Get the key size of this prf_t object.
|
||||
*
|
||||
* This is a suggestion only, all implemented PRFs accept variable key
|
||||
* length.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return key size in bytes
|
||||
|
||||
@@ -27,11 +27,6 @@
|
||||
|
||||
#include <crypto/prfs/hmac_prf.h>
|
||||
|
||||
/**
|
||||
* This class represents a hmac signer with 12 byte (96 bit) output.
|
||||
*/
|
||||
#define BLOCK_SIZE 12
|
||||
|
||||
typedef struct private_hmac_signer_t private_hmac_signer_t;
|
||||
|
||||
/**
|
||||
@@ -43,10 +38,15 @@ struct private_hmac_signer_t {
|
||||
*/
|
||||
hmac_signer_t public;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Assigned hmac function.
|
||||
*/
|
||||
prf_t *hmac_prf;
|
||||
|
||||
/**
|
||||
* Block size (truncation of HMAC Hash)
|
||||
*/
|
||||
size_t block_size;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -56,10 +56,10 @@ static void get_signature (private_hmac_signer_t *this, chunk_t data, u_int8_t *
|
||||
{
|
||||
u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
|
||||
|
||||
this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac);
|
||||
this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
|
||||
|
||||
/* copy mac aka signature :-) */
|
||||
memcpy(buffer,full_mac,BLOCK_SIZE);
|
||||
/* copy MAC depending on truncation */
|
||||
memcpy(buffer, full_mac, this->block_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,11 +72,11 @@ static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk
|
||||
|
||||
this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac);
|
||||
|
||||
signature.ptr = malloc(BLOCK_SIZE);
|
||||
signature.len = BLOCK_SIZE;
|
||||
signature.ptr = malloc(this->block_size);
|
||||
signature.len = this->block_size;
|
||||
|
||||
/* copy signature */
|
||||
memcpy(signature.ptr,full_mac,BLOCK_SIZE);
|
||||
memcpy(signature.ptr, full_mac, this->block_size);
|
||||
|
||||
*chunk = signature;
|
||||
}
|
||||
@@ -84,19 +84,19 @@ static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk
|
||||
/**
|
||||
* Implementation of signer_t.verify_signature.
|
||||
*/
|
||||
static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t signature)
|
||||
static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature)
|
||||
{
|
||||
u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
|
||||
|
||||
this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac);
|
||||
this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
|
||||
|
||||
if (signature.len != BLOCK_SIZE)
|
||||
if (signature.len != this->block_size)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* compare mac aka signature :-) */
|
||||
if (memcmp(signature.ptr,full_mac,BLOCK_SIZE) == 0)
|
||||
if (memcmp(signature.ptr, full_mac, this->block_size) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t
|
||||
/**
|
||||
* Implementation of signer_t.get_key_size.
|
||||
*/
|
||||
static size_t get_key_size (private_hmac_signer_t *this)
|
||||
static size_t get_key_size(private_hmac_signer_t *this)
|
||||
{
|
||||
/* for HMAC signer, IKEv2 uses block size as key size */
|
||||
return this->hmac_prf->get_block_size(this->hmac_prf);
|
||||
@@ -118,17 +118,17 @@ static size_t get_key_size (private_hmac_signer_t *this)
|
||||
/**
|
||||
* Implementation of signer_t.get_block_size.
|
||||
*/
|
||||
static size_t get_block_size (private_hmac_signer_t *this)
|
||||
static size_t get_block_size(private_hmac_signer_t *this)
|
||||
{
|
||||
return BLOCK_SIZE;
|
||||
return this->block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of signer_t.set_key.
|
||||
*/
|
||||
static void set_key (private_hmac_signer_t *this, chunk_t key)
|
||||
static void set_key(private_hmac_signer_t *this, chunk_t key)
|
||||
{
|
||||
this->hmac_prf->set_key(this->hmac_prf,key);
|
||||
this->hmac_prf->set_key(this->hmac_prf, key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,12 +144,12 @@ static status_t destroy(private_hmac_signer_t *this)
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm)
|
||||
hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size)
|
||||
{
|
||||
size_t hmac_block_size;
|
||||
private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t);
|
||||
|
||||
this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm);
|
||||
|
||||
if (this->hmac_prf == NULL)
|
||||
{
|
||||
/* algorithm not supported */
|
||||
@@ -157,6 +157,10 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* prevent invalid truncation */
|
||||
hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf);
|
||||
this->block_size = min(block_size, hmac_block_size);
|
||||
|
||||
/* interface functions */
|
||||
this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
|
||||
this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
|
||||
|
||||
@@ -30,9 +30,11 @@ typedef struct hmac_signer_t hmac_signer_t;
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
/**
|
||||
* @brief Implementation of signer_t interface using the
|
||||
* HMAC algorithm in combination with either MD5 or SHA1.
|
||||
*
|
||||
* @brief Implementation of signer_t interface using HMAC.
|
||||
*
|
||||
* HMAC uses a standard hash function implemented in a hasher_t to build
|
||||
* a MAC.
|
||||
*
|
||||
* @ingroup signers
|
||||
*/
|
||||
struct hmac_signer_t {
|
||||
@@ -45,15 +47,22 @@ struct hmac_signer_t {
|
||||
|
||||
/**
|
||||
* @brief Creates a new hmac_signer_t.
|
||||
*
|
||||
*
|
||||
* HMAC signatures are often truncated to shorten them to a more usable, but
|
||||
* still secure enough length.
|
||||
* Block size must be equal or smaller then the hash algorithms
|
||||
* hash.
|
||||
*
|
||||
* @param hash_algoritm Hash algorithm to use with signer
|
||||
* @param block_size Size of resulting signature (truncated to block_size)
|
||||
* @return
|
||||
* - hmac_signer_t
|
||||
* - NULL if hash algorithm not supported
|
||||
*
|
||||
* @ingroup signers
|
||||
*/
|
||||
hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm);
|
||||
hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm,
|
||||
size_t block_size);
|
||||
|
||||
|
||||
#endif /*HMAC_SIGNER_H_*/
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
|
||||
#include <crypto/signers/hmac_signer.h>
|
||||
|
||||
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_UNDEFINED,
|
||||
"UNDEFINED");
|
||||
ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_UNDEFINED,
|
||||
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
|
||||
"UNDEFINED",
|
||||
"AUTH_HMAC_SHA1_128");
|
||||
ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_HMAC_SHA1_128,
|
||||
"HMAC_MD5_96",
|
||||
"HMAC_SHA1_96",
|
||||
"DES_MAC",
|
||||
@@ -43,13 +44,11 @@ signer_t *signer_create(integrity_algorithm_t integrity_algorithm)
|
||||
switch(integrity_algorithm)
|
||||
{
|
||||
case AUTH_HMAC_SHA1_96:
|
||||
{
|
||||
return ((signer_t *) hmac_signer_create(HASH_SHA1));
|
||||
}
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA1, 12);
|
||||
case AUTH_HMAC_SHA1_128:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA1, 16);
|
||||
case AUTH_HMAC_MD5_96:
|
||||
{
|
||||
return ((signer_t *) hmac_signer_create(HASH_MD5));
|
||||
}
|
||||
return (signer_t *)hmac_signer_create(HASH_MD5, 12);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,9 @@ typedef struct signer_t signer_t;
|
||||
|
||||
/**
|
||||
* @brief Integrity algorithm, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* Currently only the following algorithms are implemented and therefore supported:
|
||||
* - AUTH_HMAC_MD5_96
|
||||
* - AUTH_HMAC_SHA1_96
|
||||
*
|
||||
*
|
||||
* Algorithms not specified in IKEv2 are allocated in private use space.
|
||||
*
|
||||
* @ingroup signers
|
||||
*/
|
||||
enum integrity_algorithm_t {
|
||||
@@ -46,7 +44,9 @@ enum integrity_algorithm_t {
|
||||
AUTH_HMAC_SHA1_96 = 2,
|
||||
AUTH_DES_MAC = 3,
|
||||
AUTH_KPDK_MD5 = 4,
|
||||
AUTH_AES_XCBC_96 = 5
|
||||
AUTH_AES_XCBC_96 = 5,
|
||||
/** Implemented via hmac_signer_t */
|
||||
AUTH_HMAC_SHA1_128 = 1025,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,6 +43,7 @@ ENUM(status_names, SUCCESS, DESTROY_ME,
|
||||
"VERIFY_ERROR",
|
||||
"INVALID_STATE",
|
||||
"DESTROY_ME",
|
||||
"NEED_MORE",
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -58,6 +59,18 @@ void *clalloc(void * pointer, size_t size)
|
||||
return (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
dest[i] ^= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We use a single mutex for all refcount variables. This
|
||||
* is not optimal for performance, but the critical section
|
||||
|
||||
@@ -226,6 +226,11 @@ enum status_t {
|
||||
* Destroy object which called method belongs to.
|
||||
*/
|
||||
DESTROY_ME,
|
||||
|
||||
/**
|
||||
* Another call to the method is required.
|
||||
*/
|
||||
NEED_MORE,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -259,6 +264,11 @@ typedef struct sockaddr sockaddr_t;
|
||||
*/
|
||||
void *clalloc(void *pointer, size_t size);
|
||||
|
||||
/**
|
||||
* Same as memcpy, but XORs src into dst instead of copy
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
|
||||
|
||||
/**
|
||||
* Special type to count references
|
||||
*/
|
||||
|
||||
@@ -186,6 +186,7 @@ whitelist_t whitelist[] = {
|
||||
{getservbyport, 311},
|
||||
{register_printf_function, 159},
|
||||
{syslog, 45},
|
||||
{dlopen, 109},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user