blob: 92fba144114c7d7db06e7eb0ecf17f1e964c1841 [file] [log] [blame]
/* test_crypt.cc - Test cryptography implementation
part of the minizip-ng project
Copyright (C) Nathan Moinvaziri
https://github.com/zlib-ng/minizip-ng
This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
*/
#include "mz.h"
#include "mz_os.h"
#include "mz_crypt.h"
#include <string>
#include <gtest/gtest.h>
#include <stdio.h> /* printf, snprintf */
#ifndef MZ_ZIP_NO_CRYPTO
static const char *hash_test_string = "the quick and lazy fox did his thang";
static void convert_buffer_to_hex_string(uint8_t *buf, int32_t buf_size, char *hex_string, int32_t max_hex_string) {
int32_t p = 0;
int32_t i = 0;
if (max_hex_string > 0)
hex_string[0] = 0;
for (i = 0, p = 0; i < (int32_t)buf_size && p < max_hex_string; i += 1, p += 2)
snprintf(hex_string + p, max_hex_string - p, "%02x", buf[i]);
if (p < max_hex_string)
hex_string[p] = 0;
}
TEST(crypt, rand) {
uint8_t random_bytes[256];
memset(random_bytes, 0, sizeof(random_bytes));
EXPECT_EQ(mz_crypt_rand(random_bytes, sizeof(random_bytes)), sizeof(random_bytes));
EXPECT_NE(std::string((char *)random_bytes).find_first_not_of('\0'), std::string::npos);
}
TEST(crypt, sha1) {
void *sha1 = NULL;
uint8_t hash1[MZ_HASH_SHA1_SIZE];
char computed_hash[256];
memset(hash1, 0, sizeof(hash1));
mz_crypt_sha_create(&sha1);
mz_crypt_sha_set_algorithm(sha1, MZ_HASH_SHA1);
mz_crypt_sha_begin(sha1);
mz_crypt_sha_update(sha1, hash_test_string, (int32_t)strlen(hash_test_string));
mz_crypt_sha_end(sha1, hash1, sizeof(hash1));
mz_crypt_sha_delete(&sha1);
convert_buffer_to_hex_string(hash1, sizeof(hash1), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "3efb8392b6cd8e14bd76bd08081521dc73df418c");
}
TEST(crypt, sha224) {
void *sha224 = NULL;
uint8_t hash224[MZ_HASH_SHA224_SIZE];
char computed_hash[256];
memset(hash224, 0, sizeof(hash224));
mz_crypt_sha_create(&sha224);
mz_crypt_sha_set_algorithm(sha224, MZ_HASH_SHA224);
mz_crypt_sha_begin(sha224);
mz_crypt_sha_update(sha224, hash_test_string, (int32_t)strlen(hash_test_string));
mz_crypt_sha_end(sha224, hash224, sizeof(hash224));
mz_crypt_sha_delete(&sha224);
convert_buffer_to_hex_string(hash224, sizeof(hash224), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "9e444f5f0b6582a923bd48696155f4a2f0d914e044cb64b8729a6600");
}
TEST(crypt, sha256) {
void *sha256 = NULL;
uint8_t hash256[MZ_HASH_SHA256_SIZE];
char computed_hash[256];
memset(hash256, 0, sizeof(hash256));
mz_crypt_sha_create(&sha256);
mz_crypt_sha_set_algorithm(sha256, MZ_HASH_SHA256);
mz_crypt_sha_begin(sha256);
mz_crypt_sha_update(sha256, hash_test_string, (int32_t)strlen(hash_test_string));
mz_crypt_sha_end(sha256, hash256, sizeof(hash256));
mz_crypt_sha_delete(&sha256);
convert_buffer_to_hex_string(hash256, sizeof(hash256), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "7a31ea0848525f7ebfeec9ee532bcc5d6d26772427e097b86cf440a56546541c");
}
TEST(crypt, sha384) {
void *sha384 = NULL;
uint8_t hash384[MZ_HASH_SHA384_SIZE];
char computed_hash[256];
memset(hash384, 0, sizeof(hash384));
mz_crypt_sha_create(&sha384);
mz_crypt_sha_set_algorithm(sha384, MZ_HASH_SHA384);
mz_crypt_sha_begin(sha384);
mz_crypt_sha_update(sha384, hash_test_string, (int32_t)strlen(hash_test_string));
mz_crypt_sha_end(sha384, hash384, sizeof(hash384));
mz_crypt_sha_delete(&sha384);
convert_buffer_to_hex_string(hash384, sizeof(hash384), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "e1e42e5977965bb3621231a5df3a1e83c471fa91fde33b6a30c8c4fa0d8be29ba7171c7c9487db91e9ee7e85049f7b41");
}
TEST(crypt, sha512) {
void *sha512 = NULL;
uint8_t hash512[MZ_HASH_SHA512_SIZE];
char computed_hash[256];
memset(hash512, 0, sizeof(hash512));
mz_crypt_sha_create(&sha512);
mz_crypt_sha_set_algorithm(sha512, MZ_HASH_SHA512);
mz_crypt_sha_begin(sha512);
mz_crypt_sha_update(sha512, hash_test_string, (int32_t)strlen(hash_test_string));
mz_crypt_sha_end(sha512, hash512, sizeof(hash512));
mz_crypt_sha_delete(&sha512);
convert_buffer_to_hex_string(hash512, sizeof(hash512), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "6627e7643ee7ce633e03f52d22329c3a32597364247c5275d4369985e1518626da46f595ad327667346479d246359b8b381af791ce2ac8c53a4788050eea11fe");
}
TEST(crypt, aes128) {
void *aes = NULL;
const char *key = "awesomekeythisis";
const char *test = "youknowitsogrowi";
int32_t key_length = 0;
int32_t test_length = 0;
uint8_t buf[120];
key_length = (int32_t)strlen(key);
test_length = (int32_t)strlen(test);
strncpy((char *)buf, test, sizeof(buf));
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_encrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_encrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STRNE((char *)buf, test);
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_decrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_decrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STREQ((char *)buf, test);
}
TEST(crypt, aes194) {
void *aes = NULL;
const char *key = "awesomekeythisisbeefyone";
const char *test = "youknowitsogrowi";
int32_t key_length = 0;
int32_t test_length = 0;
uint8_t buf[120];
key_length = (int32_t)strlen(key);
test_length = (int32_t)strlen(test);
strncpy((char *)buf, test, sizeof(buf));
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_encrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_encrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STRNE((char *)buf, test);
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_decrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_decrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STREQ((char *)buf, test);
}
TEST(crypt, aes256) {
void *aes = NULL;
const char *key = "awesomekeythisisevenmoresolidone";
const char *test = "youknowitsogrowi";
int32_t key_length = 0;
int32_t test_length = 0;
uint8_t buf[120];
key_length = (int32_t)strlen(key);
test_length = (int32_t)strlen(test);
strncpy((char *)buf, test, sizeof(buf));
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_encrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_encrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STRNE((char *)buf, test);
mz_crypt_aes_create(&aes);
mz_crypt_aes_set_decrypt_key(aes, key, key_length);
EXPECT_EQ(mz_crypt_aes_decrypt(aes, buf, test_length), 16);
mz_crypt_aes_delete(&aes);
EXPECT_STREQ((char *)buf, test);
}
TEST(crypt, hmac_sha1) {
void *hmac;
const char *key = "hm123";
const char *test = "12345678";
char computed_hash[256];
uint8_t hash1[MZ_HASH_SHA1_SIZE];
mz_crypt_hmac_create(&hmac);
mz_crypt_hmac_set_algorithm(hmac, MZ_HASH_SHA1);
mz_crypt_hmac_init(hmac, key, (int32_t)strlen(key));
mz_crypt_hmac_update(hmac, test, (int32_t)strlen(test));
mz_crypt_hmac_end(hmac, hash1, sizeof(hash1));
mz_crypt_hmac_delete(&hmac);
convert_buffer_to_hex_string(hash1, sizeof(hash1), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "c785a02ff303c886c304d9a4c06073dfe4c24aa9");
}
TEST(crypt, hmac_sha1_short_password) {
/* Test fixes for CryptImportKey returning ERROR_INVALID_PARAMETER on Windows */
void *hmac;
/* Intended key is "h", the extra "x" helps test that padding does not read past supplied length */
const char *key = "hx";
const char *test = "helloworld";
char computed_hash[256];
uint8_t hash1[MZ_HASH_SHA1_SIZE];
mz_crypt_hmac_create(&hmac);
mz_crypt_hmac_set_algorithm(hmac, MZ_HASH_SHA1);
/* Key length is 1, only first char from key should used for this test */
mz_crypt_hmac_init(hmac, key, 1);
mz_crypt_hmac_update(hmac, test, (int32_t)strlen(test));
mz_crypt_hmac_end(hmac, hash1, sizeof(hash1));
mz_crypt_hmac_delete(&hmac);
convert_buffer_to_hex_string(hash1, sizeof(hash1), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "0d216a670164deca30181479908f65b6b01199e2");
}
TEST(crypt, hmac_sha256) {
void *hmac;
const char *key = "hm123";
const char *test = "12345678";
char computed_hash[256];
uint8_t hash256[MZ_HASH_SHA256_SIZE];
mz_crypt_hmac_create(&hmac);
mz_crypt_hmac_set_algorithm(hmac, MZ_HASH_SHA256);
mz_crypt_hmac_init(hmac, key, (int32_t)strlen(key));
mz_crypt_hmac_update(hmac, test, (int32_t)strlen(test));
mz_crypt_hmac_end(hmac, hash256, sizeof(hash256));
mz_crypt_hmac_delete(&hmac);
convert_buffer_to_hex_string(hash256, sizeof(hash256), computed_hash, sizeof(computed_hash));
EXPECT_STREQ(computed_hash, "fb22a9c715a47a06bad4f6cee9badc31c921562f5d6b24adf2be009f73181f7a");
}
#ifdef HAVE_WZAES
TEST(crypt, pbkdf2) {
uint16_t iteration_count = 1000;
uint8_t key[MZ_HASH_SHA1_SIZE];
char key_hex[256];
const char *password = "passwordpasswordpasswordpassword";
const char *salt = "8F3472E4EA57F56E36F30246DC22C173";
EXPECT_EQ(mz_crypt_pbkdf2((uint8_t *)password, (int32_t)strlen(password),
(uint8_t *)salt, (int32_t)strlen(salt), iteration_count, key, (uint16_t)sizeof(key)), MZ_OK);
convert_buffer_to_hex_string(key, sizeof(key), key_hex, sizeof(key_hex));
EXPECT_STREQ(key_hex, "852c7b71a104aaa8d8996c840c3d4d5d0db780aa");
}
TEST(crypt, pbkdf2_long_odd_password) {
uint16_t iteration_count = 1000;
uint8_t key[MZ_HASH_SHA1_SIZE];
char key_hex[256];
/* Password has odd length and longer than 64 chars */
const char *password = "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordp";
const char *salt = "8F3472E4EA57F56E36F30246DC22C173";
EXPECT_EQ(mz_crypt_pbkdf2((uint8_t *)password, (int32_t)strlen(password),
(uint8_t *)salt, (int32_t)strlen(salt), iteration_count, key, (uint16_t)sizeof(key)), MZ_OK);
convert_buffer_to_hex_string(key, sizeof(key), key_hex, sizeof(key_hex));
EXPECT_STREQ(key_hex, "b3e0b5ece77332506972e97b63b3a0a6d36c39a9");
}
TEST(crypt, pbkdf2_short_password) {
/* Test fixes for CryptImportKey returns ERROR_INVALID_PARAMETER on Windows */
uint16_t iteration_count = 1000;
uint8_t key[MZ_HASH_SHA1_SIZE];
char key_hex[256];
const char *password = "p";
const char *salt = "8F3472E4EA57F56E36F30246DC22C173";
EXPECT_EQ(mz_crypt_pbkdf2((uint8_t *)password, (int32_t)strlen(password),
(uint8_t *)salt, (int32_t)strlen(salt), iteration_count, key, (uint16_t)sizeof(key)), MZ_OK);
convert_buffer_to_hex_string(key, sizeof(key), key_hex, sizeof(key_hex));
EXPECT_STREQ(key_hex, "91cf25bb4c2978620255d7fed8cc1751c7d283b9");
}
#endif
#endif