Merge branch 'hmac_support' of github.com:mrash/fwknop into hmac_support

This commit is contained in:
Damien Stuart 2013-03-10 17:17:39 -04:00
commit 19cf0d51fd
16 changed files with 446 additions and 103 deletions

View File

@ -432,7 +432,7 @@ main(int argc, char **argv)
* options, then decode it. * options, then decode it.
*/ */
res = fko_new_with_data(&ctx2, spa_data, NULL, res = fko_new_with_data(&ctx2, spa_data, NULL,
0, enc_mode, hmac_key, hmac_key_len); 0, enc_mode, hmac_key, hmac_key_len, options.hmac_type);
if(res != FKO_SUCCESS) if(res != FKO_SUCCESS)
{ {
errmsg("fko_new_with_data", res); errmsg("fko_new_with_data", res);
@ -970,7 +970,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
if (use_hmac) if (use_hmac)
{ {
res = fko_set_spa_hmac_type(ctx, FKO_HMAC_SHA256); res = fko_set_spa_hmac_type(ctx, options->hmac_type);
if(res != FKO_SUCCESS) if(res != FKO_SUCCESS)
{ {
errmsg("fko_set_spa_hmac_type", res); errmsg("fko_set_spa_hmac_type", res);
@ -1051,8 +1051,8 @@ display_ctx(fko_ctx_t ctx)
printf(" Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access); printf(" Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access);
printf(" Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth); printf(" Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth);
printf(" Client Timeout: %u\n", client_timeout); printf(" Client Timeout: %u\n", client_timeout);
printf(" Digest Type: %d\n", digest_type); printf(" Digest Type: %d (%s)\n", digest_type, digest_inttostr(digest_type));
printf(" HMAC Type: %d\n", hmac_type); printf(" HMAC Type: %d (%s)\n", hmac_type, digest_inttostr(hmac_type));
printf("Encryption Mode: %d\n", encryption_mode); printf("Encryption Mode: %d\n", encryption_mode);
printf("\n Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data); printf("\n Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data);
printf("SPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest); printf("SPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest);

View File

@ -237,7 +237,7 @@ enum {
DLL_API int fko_new(fko_ctx_t *ctx); DLL_API int fko_new(fko_ctx_t *ctx);
DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char * const enc_msg, DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char * const enc_msg,
const char * const dec_key, const int dec_key_len, int encryption_mode, const char * const dec_key, const int dec_key_len, int encryption_mode,
const char * const hmac_key, const int hmac_key_len); const char * const hmac_key, const int hmac_key_len, const int hmac_type);
DLL_API void fko_destroy(fko_ctx_t ctx); DLL_API void fko_destroy(fko_ctx_t ctx);
DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char * const enc_key, DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char * const enc_key,
const int enc_key_len, const char * const hmac_key, const int hmac_key_len); const int enc_key_len, const char * const hmac_key, const int hmac_key_len);

View File

@ -100,7 +100,7 @@ fko_errstr(const int err_code)
return("The computed digest did not match the digest in the spa data"); return("The computed digest did not match the digest in the spa data");
case FKO_ERROR_UNSUPPORTED_HMAC_MODE: case FKO_ERROR_UNSUPPORTED_HMAC_MODE:
return("Unsupported HMAC mode (default: sha256)"); return("Unsupported HMAC mode (default: SHA256)");
case FKO_ERROR_UNSUPPORTED_FEATURE: case FKO_ERROR_UNSUPPORTED_FEATURE:
return("Unsupported or unimplemented feature or function"); return("Unsupported or unimplemented feature or function");

View File

@ -172,7 +172,7 @@ int
fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg, fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg,
const char * const dec_key, const int dec_key_len, const char * const dec_key, const int dec_key_len,
int encryption_mode, const char * const hmac_key, int encryption_mode, const char * const hmac_key,
const int hmac_key_len) const int hmac_key_len, const int hmac_type)
{ {
fko_ctx_t ctx; fko_ctx_t ctx;
int res = FKO_SUCCESS; /* Are we optimistic or what? */ int res = FKO_SUCCESS; /* Are we optimistic or what? */
@ -215,6 +215,17 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg,
} }
ctx->initval = 0; ctx->initval = 0;
/* HMAC digest type
*/
ctx->initval = FKO_CTX_INITIALIZED;
res = fko_set_spa_hmac_type(ctx, hmac_type);
if(res != FKO_SUCCESS)
{
fko_destroy(ctx);
return res;
}
ctx->initval = 0;
/* Check HMAC if the access stanza had an HMAC key /* Check HMAC if the access stanza had an HMAC key
*/ */
ctx->initval = FKO_CTX_INITIALIZED; ctx->initval = FKO_CTX_INITIALIZED;
@ -357,7 +368,7 @@ fko_key_gen(char * const key_base64, const int key_len,
const int hmac_type) const int hmac_type)
{ {
unsigned char key[RIJNDAEL_MAX_KEYSIZE]; unsigned char key[RIJNDAEL_MAX_KEYSIZE];
unsigned char hmac_key[SHA256_BLOCK_LEN]; unsigned char hmac_key[SHA512_BLOCK_LEN];
int klen = 0; int klen = 0;
int hmac_klen = 0; int hmac_klen = 0;

View File

@ -40,6 +40,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
char *hmac_digest_from_data = NULL; char *hmac_digest_from_data = NULL;
char *tbuf = NULL; char *tbuf = NULL;
int res = FKO_SUCCESS; int res = FKO_SUCCESS;
int hmac_b64_digest_len = 0;
/* Must be initialized /* Must be initialized
*/ */
@ -49,17 +50,36 @@ int fko_verify_hmac(fko_ctx_t ctx,
if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
return(FKO_ERROR_INVALID_DATA); return(FKO_ERROR_INVALID_DATA);
if(ctx->hmac_type == FKO_HMAC_MD5)
hmac_b64_digest_len = MD5_B64_LEN;
else if(ctx->hmac_type == FKO_HMAC_SHA1)
hmac_b64_digest_len = SHA1_B64_LEN;
else if(ctx->hmac_type == FKO_HMAC_SHA256)
hmac_b64_digest_len = SHA256_B64_LEN;
else if(ctx->hmac_type == FKO_HMAC_SHA384)
hmac_b64_digest_len = SHA384_B64_LEN;
else if(ctx->hmac_type == FKO_HMAC_SHA512)
hmac_b64_digest_len = SHA512_B64_LEN;
else
return(FKO_ERROR_UNSUPPORTED_HMAC_MODE);
if((ctx->encrypted_msg_len - hmac_b64_digest_len)
< MIN_SPA_ENCODED_MSG_SIZE)
return(FKO_ERROR_INVALID_DATA);
/* Get digest value /* Get digest value
*/ */
hmac_digest_from_data = strndup((ctx->encrypted_msg hmac_digest_from_data = strndup((ctx->encrypted_msg
+ ctx->encrypted_msg_len - SHA256_B64_LEN), SHA256_B64_LEN); + ctx->encrypted_msg_len - hmac_b64_digest_len),
hmac_b64_digest_len);
if(hmac_digest_from_data == NULL) if(hmac_digest_from_data == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_ERROR_MEMORY_ALLOCATION);
/* Now we chop the HMAC digest off of the encrypted msg /* Now we chop the HMAC digest off of the encrypted msg
*/ */
tbuf = strndup(ctx->encrypted_msg, ctx->encrypted_msg_len - SHA256_B64_LEN); tbuf = strndup(ctx->encrypted_msg,
ctx->encrypted_msg_len - hmac_b64_digest_len);
if(tbuf == NULL) if(tbuf == NULL)
{ {
free(hmac_digest_from_data); free(hmac_digest_from_data);
@ -69,7 +89,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
free(ctx->encrypted_msg); free(ctx->encrypted_msg);
ctx->encrypted_msg = tbuf; ctx->encrypted_msg = tbuf;
ctx->encrypted_msg_len -= SHA256_B64_LEN; ctx->encrypted_msg_len -= hmac_b64_digest_len;
/* See if we need to add the "Salted__" string to the front of the /* See if we need to add the "Salted__" string to the front of the
* encrypted data. * encrypted data.
@ -86,7 +106,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
/* Calculate the HMAC from the encrypted data and then /* Calculate the HMAC from the encrypted data and then
* compare * compare
*/ */
res = fko_set_spa_hmac_type(ctx, FKO_HMAC_SHA256); res = fko_set_spa_hmac_type(ctx, ctx->hmac_type);
if(res == FKO_SUCCESS) if(res == FKO_SUCCESS)
{ {
res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len); res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
@ -94,7 +114,7 @@ int fko_verify_hmac(fko_ctx_t ctx,
if(res == FKO_SUCCESS) if(res == FKO_SUCCESS)
{ {
if(strncmp(hmac_digest_from_data, if(strncmp(hmac_digest_from_data,
ctx->msg_hmac, SHA256_B64_LEN) != 0) ctx->msg_hmac, hmac_b64_digest_len) != 0)
{ {
res = FKO_ERROR_INVALID_DATA; res = FKO_ERROR_INVALID_DATA;
} }
@ -158,36 +178,67 @@ fko_get_spa_hmac_type(fko_ctx_t ctx, short *hmac_type)
int fko_calculate_hmac(fko_ctx_t ctx, int fko_calculate_hmac(fko_ctx_t ctx,
const char * const hmac_key, const int hmac_key_len) const char * const hmac_key, const int hmac_key_len)
{ {
unsigned char hmac[SHA256_DIGEST_STR_LEN] = {0}; unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0};
char *hmac_base64 = NULL; char *hmac_base64 = NULL;
int hmac_digest_str_len = 0;
int hmac_digest_len = 0;
/* Must be initialized /* Must be initialized
*/ */
if(!CTX_INITIALIZED(ctx)) if(!CTX_INITIALIZED(ctx))
return(FKO_ERROR_CTX_NOT_INITIALIZED); return(FKO_ERROR_CTX_NOT_INITIALIZED);
memset(hmac, 0x00, SHA256_DIGEST_STR_LEN); memset(hmac, 0x00, SHA512_DIGEST_STR_LEN);
/* Only HMAC-SHA256 is supported for now if(ctx->hmac_type == FKO_HMAC_MD5)
*/ {
if(ctx->hmac_type != FKO_HMAC_SHA256) return(FKO_ERROR_CTX_NOT_INITIALIZED);
return(FKO_ERROR_UNSUPPORTED_HMAC_MODE); }
else if(ctx->hmac_type == FKO_HMAC_SHA1)
{
hmac_sha1(ctx->encrypted_msg,
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
hmac_base64 = calloc(1, MD_HEX_SIZE(SHA256_DIGEST_LEN)+1); hmac_digest_len = SHA1_DIGEST_LEN;
hmac_digest_str_len = SHA1_DIGEST_STR_LEN;
}
else if(ctx->hmac_type == FKO_HMAC_SHA256)
{
hmac_sha256(ctx->encrypted_msg,
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
hmac_digest_len = SHA256_DIGEST_LEN;
hmac_digest_str_len = SHA256_DIGEST_STR_LEN;
}
else if(ctx->hmac_type == FKO_HMAC_SHA384)
{
hmac_sha384(ctx->encrypted_msg,
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
hmac_digest_len = SHA384_DIGEST_LEN;
hmac_digest_str_len = SHA384_DIGEST_STR_LEN;
}
else if(ctx->hmac_type == FKO_HMAC_SHA512)
{
hmac_sha512(ctx->encrypted_msg,
ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
hmac_digest_len = SHA512_DIGEST_LEN;
hmac_digest_str_len = SHA512_DIGEST_STR_LEN;
}
hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1);
if (hmac_base64 == NULL) if (hmac_base64 == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_ERROR_MEMORY_ALLOCATION);
hmac_sha256(ctx->encrypted_msg, b64_encode(hmac, hmac_base64, hmac_digest_len);
ctx->encrypted_msg_len, hmac, hmac_key);
b64_encode(hmac, hmac_base64, SHA256_DIGEST_LEN);
strip_b64_eq(hmac_base64); strip_b64_eq(hmac_base64);
if(ctx->msg_hmac != NULL) if(ctx->msg_hmac != NULL)
free(ctx->msg_hmac); free(ctx->msg_hmac);
ctx->msg_hmac = strdup(hmac_base64); ctx->msg_hmac = strdup(hmac_base64);
ctx->msg_hmac_len = strnlen(ctx->msg_hmac, SHA512_DIGEST_STR_LEN); ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len);
free(hmac_base64); free(hmac_base64);

View File

@ -80,6 +80,25 @@ hmac_digest_strtoint(const char *dt_str)
return(-1); return(-1);
} }
/* Return digest string representation
*/
const char *
digest_inttostr(const int type)
{
if(type == FKO_DIGEST_MD5 || type == FKO_HMAC_MD5)
return("MD5");
else if(type == FKO_DIGEST_SHA1 || type == FKO_HMAC_SHA1)
return("SHA1");
else if(type == FKO_DIGEST_SHA256 || type == FKO_HMAC_SHA256)
return("SHA256");
else if(type == FKO_DIGEST_SHA384 || type == FKO_HMAC_SHA384)
return("SHA384");
else if(type == FKO_DIGEST_SHA512 || type == FKO_HMAC_SHA512)
return("SHA512");
return("Unknown digest type");
}
/* Validate plaintext input size /* Validate plaintext input size
*/ */
int int

View File

@ -40,6 +40,7 @@ int enc_mode_strtoint(const char *enc_mode_str);
int strtol_wrapper(const char * const str, const int min, int strtol_wrapper(const char * const str, const int min,
const int max, const int exit_upon_err, int *is_err); const int max, const int exit_upon_err, int *is_err);
short digest_strtoint(const char *dt_str); short digest_strtoint(const char *dt_str);
const char * digest_inttostr(const int type);
short hmac_digest_strtoint(const char *dt_str); short hmac_digest_strtoint(const char *dt_str);
size_t strlcat(char *dst, const char *src, size_t siz); size_t strlcat(char *dst, const char *src, size_t siz);

View File

@ -31,29 +31,126 @@
#include "hmac.h" #include "hmac.h"
void hmac_sha256(const char *msg, const unsigned int msg_len, typedef struct {
unsigned char *hmac, const char *hmac_key) SHA1_INFO ctx_inside;
SHA1_INFO ctx_outside;
unsigned char block_inner_pad[SHA1_BLOCK_LEN];
unsigned char block_outer_pad[SHA1_BLOCK_LEN];
} hmac_sha1_ctx;
typedef struct {
SHA256_CTX ctx_inside;
SHA256_CTX ctx_outside;
unsigned char block_inner_pad[SHA256_BLOCK_LEN];
unsigned char block_outer_pad[SHA256_BLOCK_LEN];
} hmac_sha256_ctx;
typedef struct {
SHA384_CTX ctx_inside;
SHA384_CTX ctx_outside;
unsigned char block_inner_pad[SHA384_BLOCK_LEN];
unsigned char block_outer_pad[SHA384_BLOCK_LEN];
} hmac_sha384_ctx;
typedef struct {
SHA512_CTX ctx_inside;
SHA512_CTX ctx_outside;
unsigned char block_inner_pad[SHA512_BLOCK_LEN];
unsigned char block_outer_pad[SHA512_BLOCK_LEN];
} hmac_sha512_ctx;
/* Begin SHA1 HMAC functions
*/
static void
hmac_sha1_init(hmac_sha1_ctx *ctx, const char *key, const int key_len)
{ {
hmac_sha256_ctx ctx; int i = 0;
memset(&ctx, 0, sizeof(&ctx)); for (i=0; i < key_len; i++) {
ctx->block_inner_pad[i] = key[i] ^ 0x36;
ctx->block_outer_pad[i] = key[i] ^ 0x5c;
}
hmac_sha256_init(&ctx, hmac_key); if(i < SHA1_BLOCK_LEN)
hmac_sha256_update(&ctx, msg, msg_len); {
hmac_sha256_final(&ctx, hmac); while(i < SHA1_BLOCK_LEN)
{
ctx->block_inner_pad[i] = 0x36;
ctx->block_outer_pad[i] = 0x5c;
i++;
}
}
sha1_init(&ctx->ctx_inside);
sha1_update(&ctx->ctx_inside, ctx->block_inner_pad, SHA1_BLOCK_LEN);
sha1_init(&ctx->ctx_outside);
sha1_update(&ctx->ctx_outside, ctx->block_outer_pad, SHA1_BLOCK_LEN);
return; return;
} }
void hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key) static void
hmac_sha1_update(hmac_sha1_ctx *ctx, const char *msg,
unsigned int msg_len)
{
sha1_update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
return;
}
static void
hmac_sha1_final(hmac_sha1_ctx *ctx, unsigned char *hmac)
{
unsigned char digest_inside[SHA1_DIGEST_LEN];
sha1_final(digest_inside, &ctx->ctx_inside);
sha1_update(&ctx->ctx_outside, digest_inside, SHA1_DIGEST_LEN);
sha1_final(hmac, &ctx->ctx_outside);
return;
}
void
hmac_sha1(const char *msg, const unsigned int msg_len,
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
{
hmac_sha1_ctx ctx;
memset(&ctx, 0, sizeof(&ctx));
hmac_sha1_init(&ctx, hmac_key, hmac_key_len);
hmac_sha1_update(&ctx, msg, msg_len);
hmac_sha1_final(&ctx, hmac);
return;
}
/* Begin SHA256 HMAC functions
*/
static void
hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len)
{ {
int i = 0; int i = 0;
for (i=0; i < (int) SHA256_BLOCK_LEN; i++) { for (i=0; i < key_len; i++) {
ctx->block_inner_pad[i] = key[i] ^ 0x36; ctx->block_inner_pad[i] = key[i] ^ 0x36;
ctx->block_outer_pad[i] = key[i] ^ 0x5c; ctx->block_outer_pad[i] = key[i] ^ 0x5c;
} }
if(i < SHA256_BLOCK_LEN)
{
while(i < SHA256_BLOCK_LEN)
{
ctx->block_inner_pad[i] = 0x36;
ctx->block_outer_pad[i] = 0x5c;
i++;
}
}
SHA256_Init(&ctx->ctx_inside); SHA256_Init(&ctx->ctx_inside);
SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN); SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN);
@ -63,14 +160,16 @@ void hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key)
return; return;
} }
void hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg, static void
hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg,
unsigned int msg_len) unsigned int msg_len)
{ {
SHA256_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); SHA256_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
return; return;
} }
void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac) static void
hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac)
{ {
unsigned char digest_inside[SHA256_DIGEST_LEN]; unsigned char digest_inside[SHA256_DIGEST_LEN];
@ -80,3 +179,151 @@ void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac)
return; return;
} }
void
hmac_sha256(const char *msg, const unsigned int msg_len,
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
{
hmac_sha256_ctx ctx;
memset(&ctx, 0, sizeof(&ctx));
hmac_sha256_init(&ctx, hmac_key, hmac_key_len);
hmac_sha256_update(&ctx, msg, msg_len);
hmac_sha256_final(&ctx, hmac);
return;
}
/* Begin SHA384 HMAC functions
*/
static void
hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len)
{
int i = 0;
for (i=0; i < key_len; i++) {
ctx->block_inner_pad[i] = key[i] ^ 0x36;
ctx->block_outer_pad[i] = key[i] ^ 0x5c;
}
if(i < SHA384_BLOCK_LEN)
{
while(i < SHA384_BLOCK_LEN)
{
ctx->block_inner_pad[i] = 0x36;
ctx->block_outer_pad[i] = 0x5c;
i++;
}
}
SHA384_Init(&ctx->ctx_inside);
SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN);
SHA384_Init(&ctx->ctx_outside);
SHA384_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA384_BLOCK_LEN);
return;
}
static void
hmac_sha384_update(hmac_sha384_ctx *ctx, const char *msg,
unsigned int msg_len)
{
SHA384_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
return;
}
static void
hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *hmac)
{
unsigned char digest_inside[SHA384_DIGEST_LEN];
SHA384_Final(digest_inside, &ctx->ctx_inside);
SHA384_Update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_LEN);
SHA384_Final(hmac, &ctx->ctx_outside);
return;
}
void
hmac_sha384(const char *msg, const unsigned int msg_len,
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
{
hmac_sha384_ctx ctx;
memset(&ctx, 0, sizeof(&ctx));
hmac_sha384_init(&ctx, hmac_key, hmac_key_len);
hmac_sha384_update(&ctx, msg, msg_len);
hmac_sha384_final(&ctx, hmac);
return;
}
/* Begin SHA512 HMAC functions
*/
static void
hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len)
{
int i = 0;
for (i=0; i < key_len; i++) {
ctx->block_inner_pad[i] = key[i] ^ 0x36;
ctx->block_outer_pad[i] = key[i] ^ 0x5c;
}
if(i < SHA512_BLOCK_LEN)
{
while(i < SHA512_BLOCK_LEN)
{
ctx->block_inner_pad[i] = 0x36;
ctx->block_outer_pad[i] = 0x5c;
i++;
}
}
SHA512_Init(&ctx->ctx_inside);
SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN);
SHA512_Init(&ctx->ctx_outside);
SHA512_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA512_BLOCK_LEN);
return;
}
static void
hmac_sha512_update(hmac_sha512_ctx *ctx, const char *msg,
unsigned int msg_len)
{
SHA512_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
return;
}
static void
hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *hmac)
{
unsigned char digest_inside[SHA512_DIGEST_LEN];
SHA512_Final(digest_inside, &ctx->ctx_inside);
SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LEN);
SHA512_Final(hmac, &ctx->ctx_outside);
return;
}
void
hmac_sha512(const char *msg, const unsigned int msg_len,
unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
{
hmac_sha512_ctx ctx;
memset(&ctx, 0, sizeof(&ctx));
hmac_sha512_init(&ctx, hmac_key, hmac_key_len);
hmac_sha512_update(&ctx, msg, msg_len);
hmac_sha512_final(&ctx, hmac);
return;
}

View File

@ -33,21 +33,14 @@
#include "digest.h" #include "digest.h"
typedef struct { void hmac_sha1(const char *msg, const unsigned int msg_len,
SHA256_CTX ctx_inside; unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
SHA256_CTX ctx_outside;
unsigned char block_inner_pad[SHA256_BLOCK_LEN];
unsigned char block_outer_pad[SHA256_BLOCK_LEN];
} hmac_sha256_ctx;
void hmac_sha256(const char *msg, const unsigned int msg_len, void hmac_sha256(const char *msg, const unsigned int msg_len,
unsigned char *hmac, const char *hmac_key); unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
void hmac_sha384(const char *msg, const unsigned int msg_len,
void hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key); unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
void hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg, void hmac_sha512(const char *msg, const unsigned int msg_len,
unsigned int msg_len); unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac);
#endif /* HMAC_H */ #endif /* HMAC_H */

View File

@ -45,7 +45,9 @@
#endif #endif
#define SHA1_BLOCKSIZE 64 #define SHA1_BLOCKSIZE 64
#define SHA1_BLOCK_LEN SHA1_BLOCKSIZE
#define SHA1_DIGEST_LEN 20 #define SHA1_DIGEST_LEN 20
#define SHA1_DIGEST_STR_LEN (SHA1_DIGEST_LEN * 2 + 1)
#define SHA1_B64_LEN 27 #define SHA1_B64_LEN 27
typedef struct { typedef struct {

View File

@ -838,9 +838,19 @@ set_acc_defaults(fko_srv_options_t *opts)
add_acc_string(&(acc->gpg_home_dir), opts->config[CONF_GPG_HOME_DIR]); add_acc_string(&(acc->gpg_home_dir), opts->config[CONF_GPG_HOME_DIR]);
} }
if (acc->encryption_mode == FKO_ENC_MODE_UNKNOWN) if(acc->encryption_mode == FKO_ENC_MODE_UNKNOWN)
acc->encryption_mode = FKO_DEFAULT_ENC_MODE; acc->encryption_mode = FKO_DEFAULT_ENC_MODE;
/* if we're using an HMAC key and the HMAC digest type was not
* set for HMAC_DIGEST_TYPE, then assume it's SHA256
*/
if(acc->hmac_type == FKO_HMAC_UNKNOWN
&& acc->hmac_key_len > 0 && acc->hmac_key != NULL)
{
acc->hmac_type = FKO_DEFAULT_HMAC_MODE;
}
acc = acc->next; acc = acc->next;
} }
} }

View File

@ -137,7 +137,7 @@ get_raw_digest(char **digest, char *pkt_data)
* we can get the outer message digest * we can get the outer message digest
*/ */
res = fko_new_with_data(&ctx, (char *)pkt_data, NULL, 0, res = fko_new_with_data(&ctx, (char *)pkt_data, NULL, 0,
FKO_DEFAULT_ENC_MODE, NULL, 0); FKO_DEFAULT_ENC_MODE, NULL, 0, 0);
if(res != FKO_SUCCESS) if(res != FKO_SUCCESS)
{ {
log_msg(LOG_WARNING, "Error initializing FKO context from SPA data: %s", log_msg(LOG_WARNING, "Error initializing FKO context from SPA data: %s",
@ -397,7 +397,7 @@ incoming_spa(fko_srv_options_t *opts)
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data,
acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key, acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key,
acc->hmac_key_len); acc->hmac_key_len, acc->hmac_type);
} }
else if(acc->use_gpg && enc_type == FKO_ENCRYPTION_GPG) else if(acc->use_gpg && enc_type == FKO_ENCRYPTION_GPG)
{ {
@ -407,7 +407,7 @@ incoming_spa(fko_srv_options_t *opts)
if(acc->gpg_decrypt_pw != NULL || acc->gpg_allow_no_pw) if(acc->gpg_decrypt_pw != NULL || acc->gpg_allow_no_pw)
{ {
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL, res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL,
0, acc->encryption_mode, NULL, 0); 0, acc->encryption_mode, NULL, 0, 0);
if(res != FKO_SUCCESS) if(res != FKO_SUCCESS)
{ {
log_msg(LOG_WARNING, log_msg(LOG_WARNING,

View File

@ -1,4 +1,5 @@
SOURCE: ANY; SOURCE: ANY;
KEY_BASE64: wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg= KEY_BASE64: wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
HMAC_KEY_BASE64: Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg== HMAC_KEY_BASE64: Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
HMAC_DIGEST_TYPE: sha1;
FW_ACCESS_TIMEOUT: 3; FW_ACCESS_TIMEOUT: 3;

View File

@ -1,4 +1,5 @@
SOURCE: ANY; SOURCE: ANY;
KEY_BASE64: wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg= KEY_BASE64: wzNP62oPPgEc+kXDPQLHPOayQBuNbYUTPP+QrErNDmg=
HMAC_KEY_BASE64: Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg== HMAC_KEY_BASE64: Yh+xizBnl6FotC5ec7FanVGClRMlsOAPh2u6eovnerfBVKwaVKzjGoblFMHMc593TNyi0dWn4opLoTIV9q/ttg==
HMAC_DIGEST_TYPE: sha384;
FW_ACCESS_TIMEOUT: 3; FW_ACCESS_TIMEOUT: 3;

View File

@ -206,38 +206,38 @@ my $openssl_hmac_ctr = 0;
my $fuzzing_success_ctr = 0; my $fuzzing_success_ctr = 0;
my $fuzzing_failure_ctr = 0; my $fuzzing_failure_ctr = 0;
my $fuzzing_ctr = 0; my $fuzzing_ctr = 0;
my $valgrind_path = ''; our $valgrind_path = '';
my $sudo_path = ''; our $sudo_path = '';
my $gcov_path = ''; our $gcov_path = '';
my $killall_path = ''; our $killall_path = '';
my $pgrep_path = ''; our $pgrep_path = '';
my $openssl_path = ''; our $openssl_path = '';
my $base64_path = ''; our $base64_path = '';
my $pinentry_fail = 0; our $pinentry_fail = 0;
my $platform = ''; our $platform = '';
my $help = 0; our $help = 0;
my $YES = 1; our $YES = 1;
my $NO = 0; our $NO = 0;
my $IGNORE = 2; our $IGNORE = 2;
my $PRINT_LEN = 68; our $PRINT_LEN = 68;
my $USE_PREDEF_PKTS = 1; our $USE_PREDEF_PKTS = 1;
my $USE_CLIENT = 2; our $USE_CLIENT = 2;
my $USE_PCAP_FILE = 3; our $USE_PCAP_FILE = 3;
my $REQUIRED = 1; our $REQUIRED = 1;
my $OPTIONAL = 0; our $OPTIONAL = 0;
my $NEW_RULE_REQUIRED = 1; our $NEW_RULE_REQUIRED = 1;
my $REQUIRE_NO_NEW_RULE = 2; our $REQUIRE_NO_NEW_RULE = 2;
my $NEW_RULE_REMOVED = 1; our $NEW_RULE_REMOVED = 1;
my $REQUIRE_NO_NEW_REMOVED = 2; our $REQUIRE_NO_NEW_REMOVED = 2;
my $MATCH_ANY = 1; our $MATCH_ANY = 1;
my $MATCH_ALL = 2; our $MATCH_ALL = 2;
my $REQUIRE_SUCCESS = 0; our $REQUIRE_SUCCESS = 0;
my $REQUIRE_FAILURE = 1; our $REQUIRE_FAILURE = 1;
my $LINUX = 1; our $LINUX = 1;
my $FREEBSD = 2; our $FREEBSD = 2;
my $MACOSX = 3; our $MACOSX = 3;
my $OPENBSD = 4; our $OPENBSD = 4;
my $start_time = time(); our $start_time = time();
my $ip_re = qr|(?:[0-2]?\d{1,2}\.){3}[0-2]?\d{1,2}|; ### IPv4 my $ip_re = qr|(?:[0-2]?\d{1,2}\.){3}[0-2]?\d{1,2}|; ### IPv4
@ -912,6 +912,7 @@ sub client_send_spa_packet() {
my $enc_mode = 0; my $enc_mode = 0;
my $is_hmac_type = 1; my $is_hmac_type = 1;
my $hmac_digest = ''; my $hmac_digest = '';
my $hmac_mode = 'sha256';
open F, "< $cmd_out_tmp" or die $!; open F, "< $cmd_out_tmp" or die $!;
while (<F>) { while (<F>) {
if (/^\s+Encoded\sData\:\s+(\S+)/) { if (/^\s+Encoded\sData\:\s+(\S+)/) {
@ -920,10 +921,12 @@ sub client_send_spa_packet() {
$digest = $1; $digest = $1;
} elsif (/Encryption\sMode\:\s+(\d+)/) { } elsif (/Encryption\sMode\:\s+(\d+)/) {
$enc_mode = $1; $enc_mode = $1;
} elsif (/^\s+HMAC.*\:\s\<NULL\>/) { } elsif (/^\s+HMAC\:\s\<NULL\>/) {
$is_hmac_type = 0; $is_hmac_type = 0;
} elsif (/^\s+HMAC.*\:\s(\S+)/) { } elsif (/^\s+HMAC\:\s(\S+)/) {
$hmac_digest = $1; $hmac_digest = $1;
} elsif (/^\s+HMAC\sType\:\s\d+\s\((\S+)\)/) {
$hmac_mode = lc($1);
} }
} }
close F; close F;
@ -963,7 +966,7 @@ sub client_send_spa_packet() {
if ($is_hmac_type and $hmac_key) { if ($is_hmac_type and $hmac_key) {
unless (&openssl_hmac_verification($encrypted_msg, unless (&openssl_hmac_verification($encrypted_msg,
$encoded_msg, '', $hmac_key, $b64_decode_key, $encoded_msg, '', $hmac_key, $b64_decode_key,
$hmac_digest)) { $hmac_digest, $hmac_mode)) {
$rv = 0; $rv = 0;
} }
} }
@ -3603,7 +3606,7 @@ sub immediate_binding() {
sub openssl_hmac_verification() { sub openssl_hmac_verification() {
my ($encrypted_msg, $encoded_msg, $access_msg, $tmp_key, my ($encrypted_msg, $encoded_msg, $access_msg, $tmp_key,
$b64_decode_key, $hmac_digest) = @_; $b64_decode_key, $hmac_digest, $hmac_mode) = @_;
$openssl_hmac_ctr++; $openssl_hmac_ctr++;
@ -3617,7 +3620,7 @@ sub openssl_hmac_verification() {
$hmac_key = $tmp_key; $hmac_key = $tmp_key;
} }
&write_test_file("[+] OpenSSL HMAC verification, (encoded msg: " . &write_test_file("[+] OpenSSL HMAC $hmac_mode verification, (encoded msg: " .
"$encoded_msg) (access: $access_msg), hmac_key: $tmp_key, " . "$encoded_msg) (access: $access_msg), hmac_key: $tmp_key, " .
"encrypted+encoded msg: $encrypted_msg, hmac_digest: $hmac_digest\n", "encrypted+encoded msg: $encrypted_msg, hmac_digest: $hmac_digest\n",
$curr_test_file); $curr_test_file);
@ -3654,7 +3657,7 @@ sub openssl_hmac_verification() {
$hex_hmac_key .= sprintf "%02x", ord($char); $hex_hmac_key .= sprintf "%02x", ord($char);
} }
my $openssl_hmac_cmd = "$openssl_path dgst -binary -sha256 -mac HMAC " . my $openssl_hmac_cmd = "$openssl_path dgst -binary -${hmac_mode} -mac HMAC " .
"-macopt hexkey:$hex_hmac_key $data_tmp"; "-macopt hexkey:$hex_hmac_key $data_tmp";
$openssl_hmac_cmd .= " | $base64_path" if $base64_path; $openssl_hmac_cmd .= " | $base64_path" if $base64_path;

View File

@ -140,9 +140,10 @@
'subcategory' => 'client+server', 'subcategory' => 'client+server',
'detail' => 'complete cycle MD5 (tcp/22 ssh)', 'detail' => 'complete cycle MD5 (tcp/22 ssh)',
'function' => \&spa_cycle, 'function' => \&spa_cycle,
'cmdline' => "$default_client_hmac_args -m md5", 'cmdline' => "$default_client_hmac_args --hmac-digest-type md5",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " . 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_hmac_conf_args $intf_str", "$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_md5_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED, 'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED, 'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'}, 'key_file' => $cf{'rc_hmac_b64_key'},
@ -153,9 +154,10 @@
'subcategory' => 'client+server', 'subcategory' => 'client+server',
'detail' => 'complete cycle SHA1 (tcp/22 ssh)', 'detail' => 'complete cycle SHA1 (tcp/22 ssh)',
'function' => \&spa_cycle, 'function' => \&spa_cycle,
'cmdline' => "$default_client_hmac_args -m sha1", 'cmdline' => "$default_client_hmac_args --hmac-digest-type sha1",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " . 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_hmac_conf_args $intf_str", "$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_sha1_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED, 'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED, 'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'}, 'key_file' => $cf{'rc_hmac_b64_key'},
@ -166,7 +168,7 @@
'subcategory' => 'client+server', 'subcategory' => 'client+server',
'detail' => 'complete cycle SHA256 (tcp/22 ssh)', 'detail' => 'complete cycle SHA256 (tcp/22 ssh)',
'function' => \&spa_cycle, 'function' => \&spa_cycle,
'cmdline' => "$default_client_hmac_args -m sha256", 'cmdline' => "$default_client_hmac_args --hmac-digest-type sha256",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " . 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_hmac_conf_args $intf_str", "$fwknopdCmd $default_server_hmac_conf_args $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED, 'fw_rule_created' => $NEW_RULE_REQUIRED,
@ -179,9 +181,10 @@
'subcategory' => 'client+server', 'subcategory' => 'client+server',
'detail' => 'complete cycle SHA384 (tcp/22 ssh)', 'detail' => 'complete cycle SHA384 (tcp/22 ssh)',
'function' => \&spa_cycle, 'function' => \&spa_cycle,
'cmdline' => "$default_client_hmac_args -m sha384", 'cmdline' => "$default_client_hmac_args --hmac-digest-type sha384",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " . 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_hmac_conf_args $intf_str", "$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_sha384_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED, 'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED, 'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'}, 'key_file' => $cf{'rc_hmac_b64_key'},
@ -192,9 +195,10 @@
'subcategory' => 'client+server', 'subcategory' => 'client+server',
'detail' => 'complete cycle SHA512 (tcp/22 ssh)', 'detail' => 'complete cycle SHA512 (tcp/22 ssh)',
'function' => \&spa_cycle, 'function' => \&spa_cycle,
'cmdline' => "$default_client_hmac_args -m sha512", 'cmdline' => "$default_client_hmac_args --hmac-digest-type sha512",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " . 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_hmac_conf_args $intf_str", "$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_sha512_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED, 'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED, 'fw_rule_removed' => $NEW_RULE_REMOVED,
'key_file' => $cf{'rc_hmac_b64_key'}, 'key_file' => $cf{'rc_hmac_b64_key'},
@ -205,8 +209,8 @@
'subcategory' => 'client', 'subcategory' => 'client',
'detail' => 'validate digest type arg', 'detail' => 'validate digest type arg',
'function' => \&generic_exec, 'function' => \&generic_exec,
'cmdline' => "$default_client_hmac_args -m invaliddigest", 'cmdline' => "$default_client_hmac_args --hmac-digest-type invaliddigest",
'positive_output_matches' => [qr/Invalid\sdigest\stype/i], 'positive_output_matches' => [qr/Invalid\shmac\sdigest\stype/i],
'fw_rule_created' => $REQUIRE_NO_NEW_RULE, 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
'key_file' => $cf{'rc_hmac_b64_key'}, 'key_file' => $cf{'rc_hmac_b64_key'},
'fatal' => $NO 'fatal' => $NO