[perl FKO] add HMAC support along with test suite HMAC verification (closes #16)

This commit is contained in:
Michael Rash 2013-03-21 21:55:18 -04:00
parent d677e18e25
commit 42cfc58e20
4 changed files with 249 additions and 6 deletions

View File

@ -189,6 +189,16 @@ _set_hmac_type(ctx, hmac_type)
OUTPUT:
RETVAL
int
_get_hmac_type(ctx, hmac_type)
INPUT:
fko_ctx_t ctx;
short hmac_type;
CODE:
RETVAL = fko_get_spa_hmac_type(ctx, hmac_type);
OUTPUT:
RETVAL
int
_set_rand_value(ctx, rand_val)
INPUT:
@ -377,6 +387,17 @@ _get_spa_digest(ctx, val)
val
RETVAL
int
_get_spa_hmac(ctx, val)
INPUT:
fko_ctx_t ctx;
char *val;
CODE:
RETVAL = fko_get_hmac_data(ctx, &val);
OUTPUT:
val
RETVAL
int
_set_spa_data(ctx, spa_data)
INPUT:
@ -606,6 +627,28 @@ _decrypt_spa_data(ctx, dec_key, dec_key_len)
OUTPUT:
RETVAL
int
_verify_hmac(ctx, hmac_key, hmac_key_len)
INPUT:
fko_ctx_t ctx;
char* hmac_key;
int hmac_key_len;
CODE:
RETVAL = fko_verify_hmac(ctx, hmac_key, hmac_key_len);
OUTPUT:
RETVAL
int
_calculate_hmac(ctx, hmac_key, hmac_key_len)
INPUT:
fko_ctx_t ctx;
char* hmac_key;
int hmac_key_len;
CODE:
RETVAL = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
OUTPUT:
RETVAL
int
_encrypt_spa_data(ctx, enc_key, enc_key_len)
INPUT:

View File

@ -73,6 +73,10 @@ sub new {
my $data = shift;
my $dc_pw = shift;
my $dc_pw_len = shift;
my $enc_mode = shift;
my $hmac_pw = shift;
my $hmac_pw_len = shift;
my $hmac_type = shift;
my $res;
my $ctx;
@ -82,7 +86,8 @@ sub new {
#
if($data) {
if(defined($dc_pw)) {
$ctx = _init_ctx_with_data($data, $dc_pw, $dc_pw_len);
$ctx = _init_ctx_with_data($data, $dc_pw, $dc_pw_len,
$enc_mode, $hmac_pw, $hmac_pw_len, $hmac_type);
} else {
$ctx = _init_ctx_with_data_only($data);
}
@ -166,6 +171,19 @@ sub digest_type {
return($self->_check_return_val($val));
}
sub hmac_type {
my $self = shift;
my $val = shift;
return FKO::_set_hmac_type($self->{_ctx}, $val)
if(defined($val));
$val = -1;
$self->{_err} = FKO::_get_hmac_type($self->{_ctx}, $val);
return($self->_check_return_val($val));
}
sub encryption_type {
my $self = shift;
my $val = shift;
@ -297,6 +315,22 @@ sub spa_digest {
return($self->_check_return_val($val));
}
sub spa_hmac {
my $self = shift;
my $recompute = shift || 0;
my $hmac_key = shift || '';
my $hmac_key_len = shift || 0;
my $val = '';
return FKO::_calculate_hmac($self->{_ctx})
if($recompute and $hmac_key and $hmac_key_len);
$self->{_err} = FKO::_get_spa_hmac($self->{_ctx}, $val);
return($self->_check_return_val($val));
}
sub spa_data {
my $self = shift;
my $val = shift;
@ -476,6 +510,22 @@ sub decode_spa_data {
return FKO::_decode_spa_data($self->{_ctx});
}
sub verify_hmac {
my $self = shift;
my $hmac_key = shift || '';
my $hmac_key_len = shift || 0;
return FKO::_verify_hmac($self->{_ctx}, $hmac_key, $hmac_key_len)
}
sub calculate_hmac {
my $self = shift;
my $hmac_key = shift || '';
my $hmac_key_len = shift || 0;
return FKO::_calculate_hmac($self->{_ctx}, $hmac_key, $hmac_key_len)
}
sub DESTROY {
my $self = shift;
FKO::_destroy_ctx($self->{_ctx}) if($self->{_ctx});
@ -545,7 +595,7 @@ FKO - Perl module wrapper for libfko
} elsif($digest_type == FKO::FKO_DIGEST_MD5) {
# do something else
}
=head1 DESCRIPTION
This module is essentially a Perl wrapper for the I<Firewall Knock Operator>

View File

@ -1832,15 +1832,19 @@ sub fuzzing_usernames() {
sub valid_encryption_keys() {
my @keys = (
'!@#$%',
'asdfasdfsafsdafasdfasdfsafsdaf',
# 'asdfasdfsafsdafasdfasdfsafsdaffdjskalfjdskl' .
# 'afjsldkafjdsajdkajsklfdafsklfjjdkljdsafjdjd' .
# 'sklfjsfdsafjdslfdkjdljsajdskjdskafjdldsljdk' .
# afdsljdslafdslaldldajdskajlddslajsl',
'$',
'asdfasdfsafsdaf',
'testtest',
'12341234',
'1',
'1234',
'a',
'$',
'!@#$%',
'asdfasdfsafsdaf',
'asdfasdfsafsdafasdfasdfsafsdaf',
);
return \@keys;
}
@ -1856,6 +1860,34 @@ sub valid_spa_digest_types() {
return \@types;
}
sub valid_spa_hmac_types() {
my @types = (
FKO->FKO_HMAC_MD5,
FKO->FKO_HMAC_SHA1,
FKO->FKO_HMAC_SHA256,
FKO->FKO_HMAC_SHA384,
FKO->FKO_HMAC_SHA512
);
return \@types;
}
sub hmac_type_to_str() {
my $hmac_type = shift;
if ($hmac_type == FKO->FKO_HMAC_MD5) {
return 'md5';
} elsif ($hmac_type == FKO->FKO_HMAC_SHA1) {
return 'sha1';
} elsif ($hmac_type == FKO->FKO_HMAC_SHA256) {
return 'sha256';
} elsif ($hmac_type == FKO->FKO_HMAC_SHA384) {
return 'sha384';
} elsif ($hmac_type == FKO->FKO_HMAC_SHA512) {
return 'sha512';
}
return 'Unknown';
}
sub fuzzing_spa_digest_types() {
my @types = (
-1,
@ -2116,6 +2148,115 @@ sub perl_fko_module_rijndael_truncated_keys() {
return $rv;
}
sub perl_fko_module_complete_cycle_hmac() {
my $test_hr = shift;
my $rv = 1;
for my $msg (@{valid_access_messages()}) {
for my $user (@{valid_usernames()}) {
for my $digest_type (@{valid_spa_digest_types()}) {
for my $hmac_type (@{valid_spa_hmac_types()}) {
my $key_ctr = 0;
KEY: for my $key (@{valid_encryption_keys()}) {
$key_ctr++;
last KEY if $key_ctr >= 2;
if ($test_hr->{'set_legacy_iv'} eq $YES
and (length($key) > 16)) {
&write_test_file("[.] Legacy IV mode is set, " .
"skipping long key '$key'.\n",
$curr_test_file);
next KEY;
}
my $hmac_key_ctr = 0;
HMAC_KEY: for my $hmac_key (@{valid_encryption_keys()}) {
$hmac_key_ctr++;
last HMAC_KEY if $hmac_key_ctr >= 4;
if ($test_hr->{'set_legacy_iv'} eq $YES
and (length($hmac_key) > 16)) {
&write_test_file("[.] Legacy IV mode is set, " .
"skipping long key '$hmac_key'.\n",
$curr_test_file);
next HMAC_KEY;
}
&write_test_file("[+] msg: $msg, user: $user, " .
"digest type: $digest_type, hmac digest type: " .
"$hmac_type, key: $key, hmac_key: $hmac_key\n",
$curr_test_file);
$fko_obj = FKO->new();
unless ($fko_obj) {
&write_test_file("[-] error FKO->new(): " . FKO::error_str() . "\n",
$curr_test_file);
return 0;
}
$fko_obj->spa_message($msg);
$fko_obj->username($user);
$fko_obj->spa_message_type(FKO->FKO_ACCESS_MSG);
$fko_obj->digest_type($digest_type);
$fko_obj->hmac_type($hmac_type);
my $enc_mode = FKO->FKO_ENC_MODE_CBC;
$enc_mode = FKO->FKO_ENC_MODE_CBC_LEGACY_IV
if $test_hr->{'set_legacy_iv'} eq $YES;
$fko_obj->encryption_mode($enc_mode);
$fko_obj->spa_data_final($key, length($key), $hmac_key, length($hmac_key));
my $encrypted_msg = $fko_obj->spa_data();
$fko_obj->destroy();
### now get new object for decryption
$fko_obj = FKO->new($encrypted_msg, $key, length($key),
$enc_mode, $hmac_key, length($hmac_key), $hmac_type);
unless ($fko_obj) {
&write_test_file("[-] error FKO->new(): " . FKO::error_str() . "\n",
$curr_test_file);
return 0;
}
$fko_obj->spa_data($encrypted_msg);
$fko_obj->hmac_type($hmac_type);
$fko_obj->encryption_mode($enc_mode);
my $hmac_digest = $fko_obj->spa_hmac();
$fko_obj->decrypt_spa_data($key, length($key), $hmac_key, length($hmac_key));
if ($msg ne $fko_obj->spa_message()) {
&write_test_file("[-] $msg encrypt/decrypt mismatch\n",
$curr_test_file);
$rv = 0;
}
$fko_obj->destroy();
if ($enable_openssl_compatibility_tests) {
unless (&openssl_hmac_verification($encrypted_msg,
'', $msg, $hmac_key, 0, $hmac_digest,
&hmac_type_to_str($hmac_type))) {
$rv = 0;
}
# my $flag = $REQUIRE_SUCCESS;
# $flag = $REQUIRE_FAILURE if $test_hr->{'set_legacy_iv'} eq $YES;
# unless (&openssl_enc_verification($encrypted_msg,
# '', $msg, $key, 0, $flag)) {
# $rv = 0;
# }
}
}
}
}
}
}
}
return $rv;
}
sub perl_fko_module_complete_cycle() {
my $test_hr = shift;

View File

@ -115,6 +115,15 @@
'set_legacy_iv' => $YES,
'fatal' => $NO
},
{
'category' => 'perl FKO module',
'subcategory' => 'HMAC encrypt/decrypt',
'detail' => 'libfko complete cycle',
'function' => \&perl_fko_module_complete_cycle_hmac,
'set_legacy_iv' => $NO,
'fatal' => $NO
},
{
'category' => 'perl FKO module',
'subcategory' => 'encrypt/decrypt',