From: Florian Forster Date: Tue, 28 Sep 2010 21:27:28 +0000 (+0200) Subject: Initial import. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=770f264eaea608c884faf1c970ae819851b6b4fc;p=create_hmac.git Initial import. --- 770f264eaea608c884faf1c970ae819851b6b4fc diff --git a/create_hmac/create_hmac.c b/create_hmac/create_hmac.c new file mode 100644 index 0000000..e966bca --- /dev/null +++ b/create_hmac/create_hmac.c @@ -0,0 +1,257 @@ +/** + * Copyright (c) 2010 Florian Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **/ + +#include "create_hmac.h" + +#include +#include +#include + +/* + * Creating a HCRYPTKEY from a plain text password is probably the most tricky + * part when calculating an RFC2104 HMAC using Microsoft CryptoAPI. The + * examples provided at the MSDN website encourage you to use "CryptDeriveKey", + * which doesn't do the conditional hashing required by HMAC. (That is, it + * might. The documentation on any of the functions is so vague that it's well + * possible the elegant solution is just not documented nor demonstrated. + */ +static HCRYPTKEY create_hmac_key_exact (HCRYPTPROV hProv, + BYTE *pbKey, DWORD dwKeySize) +{ + /* Layout of the memory expected when importing a plain text blob is + * documented at the "CryptImportKey" under "Remarks". The four bytes + * following the PUBLICKEYSTRUC structure hold the size of the key, then + * follows the key itself. */ + struct plain_text_data_s + { + PUBLICKEYSTRUC blob; + DWORD key_size; + } *data; + DWORD data_size; + HCRYPTKEY ret_key = 0; + BOOL status; + + data_size = sizeof (*data) + dwKeySize; + data = (struct plain_text_data_s *) malloc (data_size); + if (data == NULL) + return (0); + memset (data, 0, data_size); + + /* The key is not encrypted. */ + data->blob.bType = PLAINTEXTKEYBLOB; + data->blob.bVersion = CUR_BLOB_VERSION; + data->blob.reserved = 0; + /* The "CryptImportKey" page explicitly states that "RC2" is to be used for + * HMAC keys. What anyone might have been thinking, I don't know. */ + data->blob.aiKeyAlg = CALG_RC2; + + /* Copy the key to the memory right behind the struct. "memcpy" should only + * add memory protection crap *after* the region written to, so the blob + * shouldn't be destroyed. We play it save, though, and set the key size + * last. Should problems arise, we should switch to a loop just to be sure. */ + memcpy (data + 1, pbKey, dwKeySize); + data->key_size = dwKeySize; + + /* Actually convert our memory region to this mysterious key structure. + * The "CRYPT_IPSEC_HMAC_KEY" is required to allow RC2 keys longer than + * 16 byte. Again, this is documented on the "CryptImportKey" page as a + * side note. */ + status = CryptImportKey (hProv, (BYTE *) data, sizeof (data), + /* public key = */ 0, + /* flags = */ CRYPT_IPSEC_HMAC_KEY, + &ret_key); + if (!status) + { + free (data); + return (0); + } + + free (data); + return (ret_key); +} /* HCRYPTKEY create_hmac_key_exact */ + +/* If the key of the HMAC is larger than the hash size, use the hash of the + * key instead of using the key directly. */ +static HCRYPTKEY create_hmac_key_hashed (HCRYPTPROV hProv, + BYTE *pbKey, DWORD dwKeySize, + DWORD dwHashSize, HCRYPTHASH hHash) +{ + BOOL status; + BYTE *hash_data; + DWORD hash_data_size; + HCRYPTKEY key; + + assert (dwKeySize > dwHashSize); + + status = CryptHashData (hHash, pbKey, dwKeySize, /* dwFlags = */ 0); + if (!status) + return (0); + + hash_data = (BYTE *) malloc (dwHashSize); + if (hash_data == NULL) + return (0); + memset (hash_data, 0, dwHashSize); + hash_data_size = dwHashSize; + + status = CryptGetHashParam (hHash, HP_HASHVAL, + hash_data, &hash_data_size, /* flags = */ 0); + if (!status) + { + free (hash_data); + return (0); + } + + assert (hash_data_size == dwHashSize); + + key = create_hmac_key_exact (hProv, hash_data, hash_data_size); + + free (hash_data); + return (key); +} /* HCRYPTKEY create_hmac_key_hashed */ + +/* If the key is short enough, it is (right-)padded with zeros and otherwise + * used as-is. */ +static HCRYPTKEY create_hmac_key_padded (HCRYPTPROV hProv, + BYTE *pbKey, DWORD dwKeySize, + DWORD dwHashSize) +{ + BYTE *padded_key; + HCRYPTKEY key; + DWORD i; + + assert (dwKeySize <= dwHashSize); + + if (dwKeySize == dwHashSize) + return (create_hmac_key_exact (hProv, pbKey, dwKeySize)); + + padded_key = (BYTE *) malloc (dwHashSize); + if (padded_key == NULL) + return (0); + + /* Copy the key and right-pad with zeros. Don't use "memcpy" here because + * the fucked up version of VS will corrupt memory. */ + for (i = 0; i < dwHashSize; i++) + padded_key[i] = (i < dwKeySize) ? pbKey[i] : 0; + + key = create_hmac_key_exact (hProv, padded_key, dwHashSize); + + free (padded_key); + return (key); +} /* HCRYPTKEY create_hmac_key_padded */ + +static HCRYPTKEY create_hmac_key (HCRYPTPROV hProv, + ALG_ID Algid, + BYTE *pbKey, DWORD dwKeySize) +{ + HCRYPTHASH hash = 0; + HCRYPTKEY key; + DWORD hash_size = 0; + DWORD param_size; + BOOL status; + + /* Allocate a hash object to determine the hash size. */ + status = CryptCreateHash (hProv, Algid, + /* hKey = */ 0, + /* dwFlags = */ 0, + /* out phHash = */ &hash); + if (!status) + return (0); + + param_size = (DWORD) sizeof (hash_size); + status = CryptGetHashParam (hash, HP_HASHSIZE, + (BYTE *) &hash_size, ¶m_size, + /* flags = */ 0); + if (!status) + { + CryptDestroyHash (hash); + return (0); + } + + /* Determine whether we need to calculate the hash of the key or if + * padding is sufficient. */ + if (dwKeySize > hash_size) + key = create_hmac_key_hashed (hProv, pbKey, dwKeySize, hash_size, hash); + else + key = create_hmac_key_padded (hProv, pbKey, dwKeySize, hash_size); + + CryptDestroyHash (hash); + return (key); +} /* HCRYPTKEY create_hmac_key */ + +BOOL CreateHMAC (HCRYPTPROV hProv, + ALG_ID Algid, + BYTE *pbKey, DWORD dwKeySize, + DWORD dwFlags, + HCRYPTHASH *phHash, + HCRYPTKEY *phKey) +{ + HCRYPTKEY hmac_key; + HCRYPTHASH hash = 0; + HMAC_INFO hmac_info; + BOOL status; + + hmac_key = create_hmac_key (hProv, Algid, pbKey, dwKeySize); + if (hmac_key == 0) + return (FALSE); + + status = CryptCreateHash (hProv, CALG_HMAC, hmac_key, + /* flags = */ dwFlags, + &hash); + if (!status) + { + CryptDestroyKey (hmac_key); + return (status); + } + + memset (&hmac_info, 0, sizeof (hmac_info)); + hmac_info.HashAlgid = Algid; + hmac_info.pbInnerString = NULL; + hmac_info.cbInnerString = 0; + hmac_info.pbOuterString = NULL; + hmac_info.cbOuterString = 0; + + status = CryptSetHashParam (hash, HP_HMAC_INFO, (BYTE *) &hmac_info, + /* flags = */ 0); + if (!status) + { + CryptDestroyHash (hash); + CryptDestroyKey (hmac_key); + return (status); + } + + *phHash = hash; + *phKey = hmac_key; + return (TRUE); +} /* BOOL CreateHMAC */ + +BOOL DestroyHMAC (HCRYPTHASH hHash, HCRYPTKEY hKey) +{ + if (hHash != 0) + CryptDestroyHash (hHash); + + if (hKey != 0) + CryptDestroyKey (hKey); + + return (TRUE); +} /* BOOL DestroyHMAC */ + +/* vim: set ts=4 sw=4 noet : */ diff --git a/create_hmac/create_hmac.h b/create_hmac/create_hmac.h new file mode 100644 index 0000000..e6e28b8 --- /dev/null +++ b/create_hmac/create_hmac.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010 Florian Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **/ + +#ifndef CREATE_HMAC_H +#define CREATE_HMAC_H 1 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +__declspec(dllexport) +BOOL CreateHMAC (HCRYPTPROV hProv, + ALG_ID Algid, + BYTE *pbKey, DWORD dwKeySize, + DWORD dwFlags, + HCRYPTHASH *phHash, + HCRYPTKEY *phKey); + +__declspec(dllexport) +BOOL DestroyHMAC (HCRYPTHASH hHash, HCRYPTKEY hKey); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* vim: set ts=4 : */ +#endif /* CREATE_HMAC_H */ diff --git a/create_hmac/create_hmac.vcproj b/create_hmac/create_hmac.vcproj new file mode 100644 index 0000000..e449a9a --- /dev/null +++ b/create_hmac/create_hmac.vcproj @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hmac_test.sln b/hmac_test.sln new file mode 100644 index 0000000..46c7a98 --- /dev/null +++ b/hmac_test.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hmac_test", "hmac_test\hmac_test.vcproj", "{96B41CDE-A88A-42AD-A6AA-2A7A1DD62EE5}" + ProjectSection(ProjectDependencies) = postProject + {3A3F7A71-1B91-45B1-9885-F2C09BB884FD} = {3A3F7A71-1B91-45B1-9885-F2C09BB884FD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_hmac", "create_hmac\create_hmac.vcproj", "{3A3F7A71-1B91-45B1-9885-F2C09BB884FD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {96B41CDE-A88A-42AD-A6AA-2A7A1DD62EE5}.Debug|Win32.ActiveCfg = Debug|Win32 + {96B41CDE-A88A-42AD-A6AA-2A7A1DD62EE5}.Debug|Win32.Build.0 = Debug|Win32 + {96B41CDE-A88A-42AD-A6AA-2A7A1DD62EE5}.Release|Win32.ActiveCfg = Release|Win32 + {96B41CDE-A88A-42AD-A6AA-2A7A1DD62EE5}.Release|Win32.Build.0 = Release|Win32 + {3A3F7A71-1B91-45B1-9885-F2C09BB884FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {3A3F7A71-1B91-45B1-9885-F2C09BB884FD}.Debug|Win32.Build.0 = Debug|Win32 + {3A3F7A71-1B91-45B1-9885-F2C09BB884FD}.Release|Win32.ActiveCfg = Release|Win32 + {3A3F7A71-1B91-45B1-9885-F2C09BB884FD}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/hmac_test/hmac_test.cpp b/hmac_test/hmac_test.cpp new file mode 100644 index 0000000..43e5a9f --- /dev/null +++ b/hmac_test/hmac_test.cpp @@ -0,0 +1,145 @@ +#include "create_hmac.h" +#include "hmac_testcases.h" + +#include +#include +#include +#include + +static int run_single_test (HCRYPTPROV hProv, ALG_ID Algid, + BYTE *data, DWORD data_size, + BYTE *key, DWORD key_size, + const BYTE *hash, DWORD hash_size) +{ + HCRYPTHASH hmac_hash = 0; + HCRYPTKEY hmac_key = 0; + BYTE output[1024]; + DWORD output_size = 1024; + BOOL status; + + status = CreateHMAC (hProv, Algid, + key, key_size, + /* flags = */ 0, + /* phHash = */ &hmac_hash, /* phKey = */ &hmac_key); + if (!status) + { + fprintf (stderr, "CreateHMAC failed with status %#x.\n", + GetLastError ()); + return (-1); + } + + status = CryptHashData (hmac_hash, + data, data_size, + /* flags = */ 0); + if (!status) + { + fprintf (stderr, "CryptHashData failed with status %#x.\n", + GetLastError ()); + CryptDestroyHash (hmac_hash); + CryptDestroyKey (hmac_key); + return (-1); + } + + memset (output, 0, sizeof (output)); + status = CryptGetHashParam (hmac_hash, HP_HASHVAL, + output, &output_size, /* flags = */ 0); + if (!status) + { + fprintf (stderr, "CryptHashData failed with status %#x.\n", + GetLastError ()); + CryptDestroyHash (hmac_hash); + CryptDestroyKey (hmac_key); + return (-1); + } + + CryptDestroyHash (hmac_hash); + CryptDestroyKey (hmac_key); + + if (output_size != hash_size) + { + fprintf (stderr, "Hash size mismatch: Got %lu, expected %lu.\n", + output_size, hash_size); + return (-1); + } + + if (memcmp (output, hash, hash_size) != 0) + { + fprintf (stderr, "Hash sum mismatch.\n"); + return (-1); + } + else + { + printf (" Success!\n"); + } + + return (0); +} /* int run_single_test */ + +static int run_testcase (HCRYPTPROV hProv, + const testcase_t *tc) +{ + printf (" SHA-256:\n"); + run_single_test (hProv, CALG_SHA_256, + tc->data, tc->data_size, + tc->key, tc->key_size, + tc->sha256, sizeof (tc->sha256)); + printf ("\n"); + + printf (" SHA-384:\n"); + run_single_test (hProv, CALG_SHA_384, + tc->data, tc->data_size, + tc->key, tc->key_size, + tc->sha384, sizeof (tc->sha384)); + printf ("\n"); + + printf (" SHA-512:\n"); + run_single_test (hProv, CALG_SHA_512, + tc->data, tc->data_size, + tc->key, tc->key_size, + tc->sha512, sizeof (tc->sha512)); + printf ("\n"); + + return (0); +} /* int run_testcase */ + +int _tmain(int argc, _TCHAR* argv[]) +{ + HCRYPTPROV cry_provider; + BOOL status; + + status = CryptAcquireContext (&cry_provider, + /* szContainer = */ NULL, + /* CSP name = */ NULL, + /* provider type = */ PROV_RSA_AES, + /* flags = */ CRYPT_VERIFYCONTEXT); + if (!status) + { + fprintf (stderr, "CryptAcquireContext failed: %#x\n", GetLastError ()); + exit (EXIT_FAILURE); + } + + printf ("Testcase 1\n"); + printf ("----------\n"); + run_testcase (cry_provider, &testcase1); + printf ("\n"); + + printf ("Testcase 2\n"); + printf ("----------\n"); + run_testcase (cry_provider, &testcase2); + printf ("\n"); + + printf ("Testcase 3\n"); + printf ("----------\n"); + run_testcase (cry_provider, &testcase3); + printf ("\n"); + + printf ("Testcase 6\n"); + printf ("----------\n"); + run_testcase (cry_provider, &testcase6); + printf ("\n"); + + CryptReleaseContext (cry_provider, /* flags = */ 0); + + return 0; +} + diff --git a/hmac_test/hmac_test.vcproj b/hmac_test/hmac_test.vcproj new file mode 100644 index 0000000..e325ba4 --- /dev/null +++ b/hmac_test/hmac_test.vcproj @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hmac_test/hmac_testcases.h b/hmac_test/hmac_testcases.h new file mode 100644 index 0000000..ba283d6 --- /dev/null +++ b/hmac_test/hmac_testcases.h @@ -0,0 +1,185 @@ +/* + * These SHA-2 test vectors were taken from RFC 4231 which is available from + * the IETF website. + */ + +struct testcase_s +{ + BYTE *key; + DWORD key_size; + BYTE *data; + DWORD data_size; + + BYTE sha224[28]; + BYTE sha256[32]; + BYTE sha384[48]; + BYTE sha512[64]; +}; +typedef struct testcase_s testcase_t; + +BYTE testcase1_key[] = +{ + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b +}; + +BYTE testcase1_data[] = +{ + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 +}; + +testcase_t testcase1 = +{ + testcase1_key, + sizeof (testcase1_key), + testcase1_data, + sizeof (testcase1_data), + { /* SHA-224 */ + 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19, 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, + 0xf3, 0x3f, 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f, 0x53, 0x68, 0x4b, 0x22 + }, + { /* SHA-256 */ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, + 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 + }, + { /* SHA-384 */ + 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, + 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6, 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c, + 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f, 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 + }, + { /* SHA-512 */ + 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, + 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde, + 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, + 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 + } +}; + +BYTE testcase2_key[] = +{ + 0x4a, 0x65, 0x66, 0x65 +}; + +BYTE testcase2_data[] = +{ + 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x3f +}; + +testcase_t testcase2 = +{ + testcase2_key, + sizeof (testcase2_key), + testcase2_data, + sizeof (testcase2_data), + { /* SHA-224 */ + 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf, 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f, + 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00, 0x8f, 0xd0, 0x5e, 0x44 + }, + { /* SHA-256 */ + 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, + 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 + }, + { /* SHA-384 */ + 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, + 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47, 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e, + 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7, 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 + }, + { /* SHA-512 */ + 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, + 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54, + 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, + 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 + } +}; + +BYTE testcase3_key[] = +{ + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa +}; + +BYTE testcase3_data[] = +{ + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd +}; + +testcase_t testcase3 = +{ + testcase3_key, + sizeof (testcase3_key), + testcase3_data, + sizeof (testcase3_data), + { /* SHA-224 */ + 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6, 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64, + 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1, 0xec, 0x83, 0x33, 0xea + }, + { /* SHA-256 */ + 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, + 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe + }, + { /* SHA-384 */ + 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f, + 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb, 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b, + 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9, 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 + }, + { /* SHA-512 */ + 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9, + 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39, + 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8, 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, + 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb + } +}; + +BYTE testcase6_key[] = +{ + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa +}; + +BYTE testcase6_data[] = +{ + 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, + 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, + 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, + 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 +}; + +testcase_t testcase6 = +{ + testcase6_key, + sizeof (testcase6_key), + testcase6_data, + sizeof (testcase6_data), + { /* SHA-224 */ + 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad, 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2, + 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27, 0x3f, 0xa6, 0x87, 0x0e + }, + { /* SHA-256 */ + 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, + 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 + }, + { /* SHA-384 */ + 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, + 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f, 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, + 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82, 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 + }, + { /* SHA-512 */ + 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, + 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, + 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, + 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 + } +}; + +/* vim: set sw=2 sts=2 et : */