Crypt-NaCl-Sodium
view release on metacpan or search on metacpan
t/sodium_aead_aes256gcm.t view on Meta::CPAN
for my $test ( @tests ) {
my ($key_hex,
$nonce_hex,
$msg_hex,
$ad_hex,
$expected_ciphertext_hex,
$expected_mac_hex
) = @$test;
my $key = hex2bin($key_hex);
my $nonce = hex2bin($nonce_hex);
my $msg = hex2bin($msg_hex);
my $ad = hex2bin($ad_hex);
is(length($key_hex), 2 * $crypto_aead->AES256GCM_KEYBYTES, "key for $test_no is correct length");
is(length($nonce_hex), 2 * $crypto_aead->AES256GCM_NPUBBYTES, "nonce for $test_no is correct length");
is(length($expected_mac_hex), 2 * $crypto_aead->AES256GCM_ABYTES, "additional data for $test_no is correct length");
$expected_ciphertext_hex .= $expected_mac_hex;
my $precal_key = $crypto_aead->aes256gcm_beforenm($key);
isa_ok($precal_key, "Crypt::NaCl::Sodium::aead::aes256gcmstate");
my $ciphertext = $crypto_aead->aes256gcm_encrypt($msg, $ad, $nonce, $key);
is($ciphertext->to_hex, $expected_ciphertext_hex, "ciphertext is as expected: $expected_ciphertext_hex");
my $ciphertext2 = $crypto_aead->aes256gcm_encrypt_afternm($msg, $ad, $nonce, $precal_key);
is($ciphertext2->to_hex, $expected_ciphertext_hex, "ciphertext (using precalculated key) is as expected");
if ( $ciphertext->length > $crypto_aead->AES256GCM_ABYTES ) {
# at least AES256GCM_ABYTES
my $t_len = $crypto_aead->AES256GCM_ABYTES + random_number($ciphertext->length - $crypto_aead->AES256GCM_ABYTES);
eval {
my $d = $crypto_aead->aes256gcm_decrypt(
substr($ciphertext->bytes, 0, $t_len), $ad, $nonce, $key
);
};
like($@, qr/Message forged/, "Cannot decrypt truncated ciphertext");
}
eval {
my $d = $crypto_aead->aes256gcm_decrypt(
substr($ciphertext->bytes, 0, random_number($crypto_aead->AES256GCM_ABYTES)), $ad, $nonce, $key
);
};
like($@, qr/Invalid ciphertext/, "Cannot decrypt too short ciphertext");
my $decrypted = $crypto_aead->aes256gcm_decrypt($ciphertext->bytes, $ad, $nonce, $key);
is($decrypted->to_hex, $msg_hex, "message decrypted");
my $decrypted2 =
$crypto_aead->aes256gcm_decrypt_afternm($ciphertext->bytes, $ad, $nonce, $precal_key);
is($decrypted2->to_hex, $msg_hex, "message decrypted (using precalculated key)");
$test_no++;
}
my $key = "\0" x $crypto_aead->AES256GCM_KEYBYTES;
my $precal_key = $crypto_aead->aes256gcm_beforenm($key);
can_ok($precal_key, $_) for qw( lock unlock is_locked );
my $ad = "Shoppping list";
my $msg = "Milk";
my $nonce = "\0" x $crypto_aead->AES256GCM_NPUBBYTES;
ok(! $precal_key->is_locked, "precalculated key is not locked by default");
my $ciphertext = $crypto_aead->aes256gcm_encrypt_afternm($msg, $ad, $nonce,
$precal_key);
is($ciphertext->to_hex, "83ce2c56bf10b9385d1f80e635a26b3c1d1c72b7", "can encrypt with unlocked precalculated key");
my $decrypted =
$crypto_aead->aes256gcm_decrypt_afternm($ciphertext->bytes, $ad, $nonce, $precal_key);
is($decrypted->bytes, $msg, "message decrypted (using unlocked precalculated key)");
ok($precal_key->lock, "and lock the precalculated key");
ok($precal_key->is_locked, "...and confirm it using is_locked()");
eval {
my $tmp = $crypto_aead->aes256gcm_encrypt_afternm($msg, $ad, $nonce,
$precal_key);
};
like($@, qr/Unlock AES256GCM precalculated key object before accessing the state/,
"...and cannot encrypt using locked precalculated key anymore");
eval {
my $tmp =
$crypto_aead->aes256gcm_decrypt_afternm($ciphertext->bytes, $ad, $nonce, $precal_key);
};
like($@, qr/Unlock AES256GCM precalculated key object before accessing the state/,
"...and cannot decrypt using locked precalculated key anymore");
ok($precal_key->unlock, "but can unlock the precalculated key");
ok(! $precal_key->is_locked, "...and confirm it using is_locked()");
my $decrypted2 =
$crypto_aead->aes256gcm_decrypt_afternm($ciphertext->bytes, $ad, $nonce, $precal_key);
is($decrypted2->bytes, $msg, "to decrypted the message (using unlocked precalculated key)");
}
SKIP: {
skip "AES256GCM is available", 1 if $is_available;
my @noargs_methods = qw(
AES256GCM_KEYBYTES
AES256GCM_NPUBBYTES
AES256GCM_ABYTES
aes256gcm_keygen
aes256gcm_nonce
);
for my $m ( @noargs_methods ) {
eval {
$crypto_aead->$m();
};
like($@, qr/AES256-GCM is not supported by this CPU/, "$m is not available");
}
eval {
my $ciphertext = $crypto_aead->aes256gcm_encrypt("msg", "", "\0", "\0");
};
like($@, qr/AES256-GCM is not supported by this CPU/, "aes256gcm_encrypt is not available");
eval {
my $plain = $crypto_aead->aes256gcm_decrypt("ciphertext", "", "\0", "\0");
};
like($@, qr/AES256-GCM is not supported by this CPU/, "aes256gcm_decrypt is not available");
eval {
my $precal_key = $crypto_aead->aes256gcm_beforenm("\0");
};
like($@, qr/AES256-GCM is not supported by this CPU/, "aes256gcm_beforenm is not available");
eval {
my $ciphertext = $crypto_aead->aes256gcm_encrypt_afternm("msg", "", "\0", "\0");
};
like($@, qr/AES256-GCM is not supported by this CPU/, "aes256gcm_encrypt_afternm is not available");
eval {
my $plain = $crypto_aead->aes256gcm_decrypt_afternm("ciphertext", "", "\0", "\0");
};
like($@, qr/AES256-GCM is not supported by this CPU/, "aes256gcm_decrypt_afternm is not available");
}
done_testing();
( run in 2.588 seconds using v1.01-cache-2.11-cpan-364913b4093 )