summaryrefslogtreecommitdiffhomepage
path: root/libtomcrypt/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libtomcrypt/tests')
-rw-r--r--libtomcrypt/tests/base64_test.c134
-rw-r--r--libtomcrypt/tests/cipher_hash_test.c46
-rw-r--r--libtomcrypt/tests/common.c68
-rw-r--r--libtomcrypt/tests/common.h32
-rw-r--r--libtomcrypt/tests/der_test.c1451
-rw-r--r--libtomcrypt/tests/dh_test.c454
-rw-r--r--libtomcrypt/tests/dsa_test.c400
-rw-r--r--libtomcrypt/tests/ecc_test.c268
-rw-r--r--libtomcrypt/tests/file_test.c115
-rw-r--r--libtomcrypt/tests/katja_test.c242
-rw-r--r--libtomcrypt/tests/mac_test.c64
-rw-r--r--libtomcrypt/tests/misc_test.c33
-rw-r--r--libtomcrypt/tests/modes_test.c130
-rw-r--r--libtomcrypt/tests/mpi_test.c147
-rw-r--r--libtomcrypt/tests/multi_test.c237
-rw-r--r--libtomcrypt/tests/no_prng.c185
-rw-r--r--libtomcrypt/tests/pkcs_1_eme_test.c78
-rw-r--r--libtomcrypt/tests/pkcs_1_emsa_test.c72
-rw-r--r--libtomcrypt/tests/pkcs_1_oaep_test.c78
-rw-r--r--libtomcrypt/tests/pkcs_1_pss_test.c79
-rw-r--r--libtomcrypt/tests/pkcs_1_test.c106
-rw-r--r--libtomcrypt/tests/prng_test.c90
-rw-r--r--libtomcrypt/tests/rotate_test.c416
-rw-r--r--libtomcrypt/tests/rsa_test.c702
-rw-r--r--libtomcrypt/tests/store_test.c86
-rw-r--r--libtomcrypt/tests/test.c433
-rw-r--r--libtomcrypt/tests/test.derbin0 -> 162 bytes
-rw-r--r--libtomcrypt/tests/test.key15
-rw-r--r--libtomcrypt/tests/test_dsa.key12
-rw-r--r--libtomcrypt/tests/tomcrypt_test.h69
30 files changed, 6242 insertions, 0 deletions
diff --git a/libtomcrypt/tests/base64_test.c b/libtomcrypt/tests/base64_test.c
new file mode 100644
index 0000000..b5b5e93
--- /dev/null
+++ b/libtomcrypt/tests/base64_test.c
@@ -0,0 +1,134 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_BASE64) || defined(LTC_BASE64_URL)
+int base64_test(void)
+{
+ unsigned char in[64], out[256], tmp[64];
+ unsigned long x, l1, l2, slen1;
+
+ const unsigned char special_case[] = {
+ 0xbe, 0xe8, 0x92, 0x3c, 0xa2, 0x25, 0xf0, 0xf8,
+ 0x91, 0xe4, 0xef, 0xab, 0x0b, 0x8c, 0xfd, 0xff,
+ 0x14, 0xd0, 0x29, 0x9d, 0x00 };
+
+#if defined(LTC_BASE64)
+ /*
+ TEST CASES SOURCE:
+
+ Network Working Group S. Josefsson
+ Request for Comments: 4648 SJD
+ Obsoletes: 3548 October 2006
+ Category: Standards Track
+ */
+ const struct {
+ const char* s;
+ const char* b64;
+ } cases[] = {
+ {"", "" },
+ {"f", "Zg==" },
+ {"fo", "Zm8=" },
+ {"foo", "Zm9v" },
+ {"foob", "Zm9vYg==" },
+ {"fooba", "Zm9vYmE=" },
+ {"foobar", "Zm9vYmFy"},
+ {(char*)special_case,"vuiSPKIl8PiR5O+rC4z9/xTQKZ0="}
+ };
+#endif
+
+#ifdef LTC_BASE64_URL
+ const struct {
+ const char* s;
+ int is_strict;
+ } url_cases[] = {
+ {"vuiSPKIl8PiR5O-rC4z9_xTQKZ0", 0},
+ {"vuiSPKIl8PiR5O-rC4z9_xTQKZ0=", 1},
+ {"vuiS*PKIl8P*iR5O-rC4*z9_xTQKZ0", 0},
+ {"vuiS*PKIl8P*iR5O-rC4*z9_xTQKZ0=", 0},
+ {"vuiS*PKIl8P*iR5O-rC4*z9_xTQKZ0==", 0},
+ {"vuiS*PKIl8P*iR5O-rC4*z9_xTQKZ0===", 0},
+ {"vuiS*PKIl8P*iR5O-rC4*z9_xTQKZ0====", 0},
+ {"vuiS*=PKIl8P*iR5O-rC4*z9_xTQKZ0=", 0},
+ {"vuiS*==PKIl8P*iR5O-rC4*z9_xTQKZ0=", 0},
+ {"vuiS*===PKIl8P*iR5O-rC4*z9_xTQKZ0=", 0},
+ };
+
+ for (x = 0; x < sizeof(url_cases)/sizeof(url_cases[0]); ++x) {
+ slen1 = strlen(url_cases[x].s);
+ l1 = sizeof(out);
+ if(url_cases[x].is_strict)
+ DO(base64url_strict_decode((unsigned char*)url_cases[x].s, slen1, out, &l1));
+ else
+ DO(base64url_decode((unsigned char*)url_cases[x].s, slen1, out, &l1));
+ if (compare_testvector(out, l1, special_case, sizeof(special_case) - 1, "base64url decode", x)) {
+ return 1;
+ }
+ if(x < 2) {
+ l2 = sizeof(tmp);
+ if(x == 0)
+ DO(base64url_encode(out, l1, tmp, &l2));
+ else
+ DO(base64url_strict_encode(out, l1, tmp, &l2));
+ if (compare_testvector(tmp, l2, url_cases[x].s, strlen(url_cases[x].s), "base64url encode", x)) {
+ return 1;
+ }
+ }
+ }
+
+ DO(base64url_strict_decode((unsigned char*)url_cases[4].s, slen1, out, &l1) == CRYPT_INVALID_PACKET ? CRYPT_OK : CRYPT_INVALID_PACKET);
+#endif
+
+#if defined(LTC_BASE64)
+ for (x = 0; x < sizeof(cases)/sizeof(cases[0]); ++x) {
+ memset(out, 0, sizeof(out));
+ memset(tmp, 0, sizeof(tmp));
+ slen1 = strlen(cases[x].s);
+ l1 = sizeof(out);
+ DO(base64_encode((unsigned char*)cases[x].s, slen1, out, &l1));
+ l2 = sizeof(tmp);
+ DO(base64_strict_decode(out, l1, tmp, &l2));
+ if (compare_testvector(out, l1, cases[x].b64, strlen(cases[x].b64), "base64 encode", x) ||
+ compare_testvector(tmp, l2, cases[x].s, slen1, "base64 decode", x)) {
+ return 1;
+ }
+ }
+
+ for (x = 0; x < 64; x++) {
+ yarrow_read(in, x, &yarrow_prng);
+ l1 = sizeof(out);
+ DO(base64_encode(in, x, out, &l1));
+ l2 = sizeof(tmp);
+ DO(base64_decode(out, l1, tmp, &l2));
+ if (compare_testvector(tmp, x, in, x, "random base64", x)) {
+ return 1;
+ }
+ }
+
+ x--;
+ memmove(&out[11], &out[10], l1 - 10);
+ out[10] = '=';
+ l1++;
+ l2 = sizeof(tmp);
+ DO(base64_decode(out, l1, tmp, &l2));
+ if (compare_testvector(tmp, l2, in, l2, "relaxed base64 decoding", -1)) {
+ print_hex("input ", out, l1);
+ return 1;
+ }
+ l2 = sizeof(tmp);
+ DO(base64_strict_decode(out, l1, tmp, &l2) == CRYPT_INVALID_PACKET ? CRYPT_OK : CRYPT_INVALID_PACKET);
+#endif
+
+ return 0;
+}
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/cipher_hash_test.c b/libtomcrypt/tests/cipher_hash_test.c
new file mode 100644
index 0000000..3d9aea4
--- /dev/null
+++ b/libtomcrypt/tests/cipher_hash_test.c
@@ -0,0 +1,46 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+/* test the ciphers and hashes using their built-in self-tests */
+
+#include <tomcrypt_test.h>
+
+int cipher_hash_test(void)
+{
+ int x;
+
+ /* test ciphers */
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name);
+ }
+
+ /* stream ciphers */
+#ifdef LTC_CHACHA
+ DO(chacha_test());
+#endif
+#ifdef LTC_RC4_STREAM
+ DO(rc4_stream_test());
+#endif
+#ifdef LTC_SOBER128_STREAM
+ DO(sober128_stream_test());
+#endif
+
+ /* test hashes */
+ for (x = 0; hash_descriptor[x].name != NULL; x++) {
+ DOX(hash_descriptor[x].test(), hash_descriptor[x].name);
+ }
+
+ /* SHAKE128 + SHAKE256 tests are a bit special */
+ DOX(sha3_shake_test(), "sha3_shake");
+
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/common.c b/libtomcrypt/tests/common.c
new file mode 100644
index 0000000..18a5614
--- /dev/null
+++ b/libtomcrypt/tests/common.c
@@ -0,0 +1,68 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "common.h"
+
+/**
+ @file common.c
+
+ Steffen Jaeckel
+*/
+
+void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm)
+{
+ if (res != CRYPT_OK) {
+ fprintf(stderr, "%s (%d)%s%s\n%s:%d:%s\n",
+ error_to_string(res), res,
+ (algorithm ? " - " : ""), (algorithm ? algorithm : ""),
+ file, line, cmd);
+ if (res != CRYPT_NOP) {
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+void print_hex(const char* what, const void* v, const unsigned long l)
+{
+ const unsigned char* p = v;
+ unsigned long x, y = 0, z;
+ fprintf(stderr, "%s contents: \n", what);
+ for (x = 0; x < l; ) {
+ fprintf(stderr, "%02X ", p[x]);
+ if (!(++x % 16) || x == l) {
+ if((x % 16) != 0) {
+ z = 16 - (x % 16);
+ if(z >= 8)
+ fprintf(stderr, " ");
+ for (; z != 0; --z) {
+ fprintf(stderr, " ");
+ }
+ }
+ fprintf(stderr, " | ");
+ for(; y < x; y++) {
+ if((y % 8) == 0)
+ fprintf(stderr, " ");
+ if(isgraph(p[y]))
+ fprintf(stderr, "%c", p[y]);
+ else
+ fprintf(stderr, ".");
+ }
+ fprintf(stderr, "\n");
+ }
+ else if((x % 8) == 0) {
+ fprintf(stderr, " ");
+ }
+ }
+}
+
+prng_state yarrow_prng;
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/common.h b/libtomcrypt/tests/common.h
new file mode 100644
index 0000000..410db1e
--- /dev/null
+++ b/libtomcrypt/tests/common.h
@@ -0,0 +1,32 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#ifndef DEMOS_COMMON_H_
+#define DEMOS_COMMON_H_
+
+#include <tomcrypt.h>
+
+extern prng_state yarrow_prng;
+
+#ifdef LTC_VERBOSE
+#define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
+#define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
+#else
+#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
+#define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
+#endif
+
+void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm);
+
+void print_hex(const char* what, const void* v, const unsigned long l);
+
+#endif /* DEMOS_COMMON_H_ */
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/der_test.c b/libtomcrypt/tests/der_test.c
new file mode 100644
index 0000000..6dab424
--- /dev/null
+++ b/libtomcrypt/tests/der_test.c
@@ -0,0 +1,1451 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+#if defined(GMP_LTC_DESC) || defined(USE_GMP)
+#include <gmp.h>
+#endif
+
+#if !defined(LTC_DER) || !defined(LTC_TEST_MPI)
+
+int der_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#else
+
+static const unsigned char _der_tests_stinky_root_cert[] =
+ "MIIFETCCA/mgAwIBAgIQbv53JNmv518t5lkCHE272jANBgkqhkiG9w0BAQUFADCB"
+ "lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug"
+ "Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho"
+ "dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt"
+ "T2JqZWN0MB4XDTA4MDQyOTAwMDAwMFoXDTEwMDQyOTIzNTk1OVowgbUxCzAJBgNV"
+ "BAYTAlVTMQ4wDAYDVQQRDAU0NDE0MzELMAkGA1UECAwCT0gxGTAXBgNVBAcMEE1h"
+ "eWZpZWxkIFZpbGxhZ2UxEDAOBgNVBAkMB1N1aXRlIEExFDASBgNVBAkMCzc2NyBC"
+ "ZXRhIERyMSIwIAYDVQQKDBlQcmVlbXB0aXZlIFNvbHV0aW9ucywgTExDMSIwIAYD"
+ "VQQDDBlQcmVlbXB0aXZlIFNvbHV0aW9ucywgTExDMIIBIjANBgkqhkiG9w0BAQEF"
+ "AAOCAQ8AMIIBCgKCAQEAzH7ZBkMcBuHx8d2f10RGTHAf7gzzVteGbOihJGH2BwlS"
+ "ZvNp6WEE4DfL+s1vp0wzk1XeLN5tRjg2qum9YqyCk7okh7pXGy46f5mWbLQiefGA"
+ "j5UXRcr6WJ3xeACdbXxKrYMV0REia+4Jb2UbFA8S81PjhRon6vcRz76ziUWwt8NC"
+ "igX+4ZC0skhhKzKszel6KGL7bJCtLG7ukw9DZCrvPCRcKFeM/GwQ6ACMgP88CSCL"
+ "t1fbIXDH1vd/x2XM3QlaSDN6hYDbef8m1T+9TCkXVKeqG1GYjSUrHzYnCZUmTRrR"
+ "38jgC3qXxiIpDKW105uM0nlXe2XF9c+ot2MdWvV4TwIDAQABo4IBOTCCATUwHwYD"
+ "VR0jBBgwFoAU2u1kdBScFDyr3ZmpvVsoTYs8ydgwHQYDVR0OBBYEFK+1HzZE4i28"
+ "oLIzuqlFR9SspiCIMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1Ud"
+ "JQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBGBgNVHSAEPzA9MDsG"
+ "DCsGAQQBsjEBAgEDAjArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21v"
+ "ZG8ubmV0L0NQUzBCBgNVHR8EOzA5MDegNaAzhjFodHRwOi8vY3JsLnVzZXJ0cnVz"
+ "dC5jb20vVVROLVVTRVJGaXJzdC1PYmplY3QuY3JsMCEGA1UdEQQaMBiBFnN1cHBv"
+ "cnRAcHJlZW1wdGl2ZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAC+JM26Dokvonudl"
+ "JXe/Yun7IBhimkagZUjbk9l/GQWN6i+v1o95UJ1wGJtBdm2+MxbSaPoNTDZR4B+2"
+ "lYL9MW57UVmePrnfUPXQKZZG+8gTRDz8+7ol/CEAKmS3MLKCRcH5oe+J5345sGxi"
+ "FC/KWNKedTNraW95xlg8NTlL2yRP7TMsjvBxgLmkbaFUoXzPTbQWmtovIagIT8GC"
+ "JeXwdFaRjbamiz3Irl+u7x/mhxdza6RvgBYylXRFMudANpeGsV7gDXlnfzpFDKHQ"
+ "niVwB7P5sbPFIlmIc+4/xRItkLIRjCVXaepgN9KYu3VOgiSDI6wXiTwP44/LUXQM"
+ "hetwa7s=";
+const unsigned char _der_tests_cacert_root_cert[] =
+ "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290"
+ "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB"
+ "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA"
+ "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO"
+ "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi"
+ "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ"
+ "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC"
+ "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ"
+ "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6"
+ "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y"
+ "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7"
+ "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc"
+ "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k"
+ "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q"
+ "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ"
+ "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU"
+ "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826"
+ "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w"
+ "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY"
+ "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe"
+ "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0"
+ "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy"
+ "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw"
+ "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0"
+ "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl"
+ "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC"
+ "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg"
+ "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB"
+ "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc"
+ "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg"
+ "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c"
+ "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl"
+ "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY"
+ "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T"
+ "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF"
+ "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum"
+ "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk"
+ "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW"
+ "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD";
+const unsigned long _der_tests_cacert_root_cert_size = sizeof(_der_tests_cacert_root_cert);
+
+/*
+SEQUENCE(3 elem)
+ SEQUENCE(8 elem)
+ [0](1)
+ INTEGER 2
+ INTEGER 0
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.1.4
+ NULL
+ SEQUENCE(4 elem)
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.10
+ PrintableString Root CA
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.11
+ PrintableString http://www.cacert.org
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.3
+ PrintableString CA Cert Signing Authority
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.9.1
+ IA5String support@cacert.org
+ SEQUENCE(2 elem)
+ UTCTime03-03-30 12:29:49 UTC
+ UTCTime33-03-29 12:29:49 UTC
+ SEQUENCE(4 elem)
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.10
+ PrintableString Root CA
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.11
+ PrintableString http://www.cacert.org
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.3
+ PrintableString CA Cert Signing Authority
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.9.1
+ IA5String support@cacert.org
+ SEQUENCE(2 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.1.1
+ NULL
+ BIT STRING(1 elem)
+ SEQUENCE(2 elem)
+ INTEGER (4096 bit)
+ INTEGER 65537
+ [3](1)
+ SEQUENCE(7 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.29.14
+ OCTET STRING(1 elem)
+ OCTET STRING(20 byte) 16B5321BD4C7F3E0E68EF3BDD2B03AEEB23918D1
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.29.35
+ OCTET STRING(1 elem)
+ SEQUENCE(3 elem)
+ [0]
+ [1](1)
+ [4](1)
+ SEQUENCE(4 elem)
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.10
+ PrintableString Root CA
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.11
+ PrintableString http://www.cacert.org
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.3
+ PrintableString CA Cert Signing Authority
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.9.1
+ IA5String support@cacert.org
+ [2]
+ SEQUENCE(3 elem)
+ OBJECT IDENTIFIER 2.5.29.19
+ BOOLEAN true
+ OCTET STRING(1 elem)
+ SEQUENCE(1 elem)
+ BOOLEAN true
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.29.31
+ OCTET STRING(1 elem)
+ SEQUENCE(1 elem)
+ SEQUENCE(1 elem)
+ [0](1)
+ [0](1)
+ [6]
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.16.840.1.113730.1.4
+ OCTET STRING(1 elem)
+ IA5String https://www.cacert.org/revoke.crl
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.16.840.1.113730.1.8
+ OCTET STRING(1 elem)
+ IA5String http://www.cacert.org/index.php?id=10
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.16.840.1.113730.1.13
+ OCTET STRING(1 elem)
+ IA5String To get your own certificate for FREE head over to http://www.cacert.org
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.1.4
+ NULL
+ BIT STRING(4096 bit)
+ */
+
+#define __ASN1_FMTSTRING_FMT "line: %d, type=%d, size=%lu, data=%p, self=%p, next=%p, prev=%p, parent=%p, child=%p"
+#define __ASN1_FMTSTRING_VAL(l) __LINE__, (l)->type, (l)->size, (l)->data, (l), (l)->next, (l)->prev, (l)->parent, (l)->child
+
+#define __ASN1_ERR(l) fprintf(stderr, __ASN1_FMTSTRING_FMT "\n", __ASN1_FMTSTRING_VAL(l)); \
+ exit(EXIT_FAILURE)
+
+#define __CHECK_ASN1_HAS(l, w) do { if ((l)->w == NULL) { \
+ __ASN1_ERR(l);\
+} } while(0)
+
+#define __CHECK_ASN1_HAS_NO(l, w) do { if ((l)->w != NULL) { \
+ __ASN1_ERR(l);\
+} } while(0)
+
+
+
+#define CHECK_ASN1_TYPE(l, t) do { if ((l)->type != (t)) { \
+ __ASN1_ERR(l);\
+} } while(0)
+
+#define CHECK_ASN1_HAS_CHILD(l) __CHECK_ASN1_HAS(l, child)
+#define CHECK_ASN1_HAS_NO_CHILD(l) __CHECK_ASN1_HAS_NO(l, child)
+#define CHECK_ASN1_HAS_NEXT(l) __CHECK_ASN1_HAS(l, next)
+#define CHECK_ASN1_HAS_NO_NEXT(l) __CHECK_ASN1_HAS_NO(l, next)
+#define CHECK_ASN1_HAS_DATA(l) __CHECK_ASN1_HAS(l, data)
+#define CHECK_ASN1_HAS_NO_DATA(l) __CHECK_ASN1_HAS_NO(l, data)
+
+#ifdef LTC_DER_TESTS_PRINT_FLEXI
+static void _der_tests_print_flexi(ltc_asn1_list* l, unsigned int level)
+{
+ char buf[1024];
+ const char* name = NULL;
+ const char* text = NULL;
+ ltc_asn1_list* ostring = NULL;
+ unsigned int n;
+
+ switch (l->type)
+ {
+ case LTC_ASN1_EOL:
+ name = "EOL";
+ snprintf(buf, sizeof(buf),__ASN1_FMTSTRING_FMT "\n", __ASN1_FMTSTRING_VAL(l));
+ text = buf;
+ break;
+ case LTC_ASN1_BOOLEAN:
+ name = "BOOLEAN";
+ {
+ if (*(int*)l->data)
+ text = "true";
+ else
+ text = "false";
+ }
+ break;
+ case LTC_ASN1_INTEGER:
+ name = "INTEGER";
+ break;
+ case LTC_ASN1_SHORT_INTEGER:
+ name = "SHORT INTEGER";
+ break;
+ case LTC_ASN1_BIT_STRING:
+ name = "BIT STRING";
+ break;
+ case LTC_ASN1_OCTET_STRING:
+ name = "OCTET STRING";
+ {
+ unsigned long ostring_l = l->size;
+ /* sometimes there's another sequence in an octet string...
+ * try to decode that... if it fails print out the octet string
+ */
+ if (der_decode_sequence_flexi(l->data, &ostring_l, &ostring) == CRYPT_OK) {
+ text = "";
+ }
+ else {
+ int r;
+ char* s = buf;
+ int sz = sizeof(buf);
+ for (n = 0; n < l->size; ++n) {
+ r = snprintf(s, sz, "%02X", ((unsigned char*)l->data)[n]);
+ if (r < 0 || r >= sz) {
+ fprintf(stderr, "%s boom\n", name);
+ exit(EXIT_FAILURE);
+ }
+ s += r;
+ sz -= r;
+ }
+ text = buf;
+ }
+ }
+ break;
+ case LTC_ASN1_NULL:
+ name = "NULL";
+ text = "";
+ break;
+ case LTC_ASN1_OBJECT_IDENTIFIER:
+ name = "OBJECT IDENTIFIER";
+ {
+ unsigned long i;
+ int r;
+ char* s = buf;
+ int sz = sizeof(buf);
+ for (i = 0; i < l->size; ++i) {
+ r = snprintf(s, sz, "%lu.", ((unsigned long*)l->data)[i]);
+ if (r < 0 || r >= sz) {
+ fprintf(stderr, "%s boom\n", name);
+ exit(EXIT_FAILURE);
+ }
+ s += r;
+ sz -= r;
+ }
+ /* replace the last . with a \0 */
+ *(s - 1) = '\0';
+ text = buf;
+ }
+ break;
+ case LTC_ASN1_IA5_STRING:
+ name = "IA5 STRING";
+ text = l->data;
+ break;
+ case LTC_ASN1_PRINTABLE_STRING:
+ name = "PRINTABLE STRING";
+ text = l->data;
+ break;
+ case LTC_ASN1_UTF8_STRING:
+ name = "UTF8 STRING";
+ break;
+ case LTC_ASN1_UTCTIME:
+ name = "UTCTIME";
+ {
+ ltc_utctime* ut = l->data;
+ snprintf(buf, sizeof(buf), "%02d-%02d-%02d %02d:%02d:%02d %c%02d:%02d",
+ ut->YY, ut->MM, ut->DD, ut->hh, ut->mm, ut->ss,
+ ut->off_dir ? '-' : '+', ut->off_hh, ut->off_mm);
+ text = buf;
+ }
+ break;
+ case LTC_ASN1_GENERALIZEDTIME:
+ name = "GENERALIZED TIME";
+ {
+ ltc_generalizedtime* gt = l->data;
+ if(gt->fs)
+ snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%02dZ",
+ gt->YYYY, gt->MM, gt->DD, gt->hh, gt->mm, gt->ss, gt->fs);
+ else
+ snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02dZ",
+ gt->YYYY, gt->MM, gt->DD, gt->hh, gt->mm, gt->ss);
+ text = buf;
+ }
+ break;
+ case LTC_ASN1_CHOICE:
+ name = "CHOICE";
+ break;
+ case LTC_ASN1_SEQUENCE:
+ name = "SEQUENCE";
+ text = "";
+ break;
+ case LTC_ASN1_SET:
+ name = "SET";
+ text = "";
+ break;
+ case LTC_ASN1_SETOF:
+ name = "SETOF";
+ text = "";
+ break;
+ case LTC_ASN1_RAW_BIT_STRING:
+ name = "RAW BIT STRING";
+ break;
+ case LTC_ASN1_TELETEX_STRING:
+ name = "TELETEX STRING";
+ text = l->data;
+ break;
+ case LTC_ASN1_CONSTRUCTED:
+ if (l->used & 0x80)
+ name = "CONTEXT SPECIFIC";
+ else
+ name = "CONSTRUCTED";
+ snprintf(buf, sizeof(buf), "[%d]", l->used & 0x1f);
+ text = buf;
+ break;
+ case LTC_ASN1_CONTEXT_SPECIFIC:
+ name = "CONTEXT SPECIFIC";
+ {
+ int r;
+ char* s = buf;
+ int sz = sizeof(buf);
+ r = snprintf(s, sz, "[%d] ", l->used & 0x1f);
+ if (r < 0 || r >= sz) {
+ printf("Context Specific boom");
+ exit(EXIT_FAILURE);
+ }
+ s += r;
+ sz -= r;
+ for (n = 0; n < l->size; ++n) {
+ r = snprintf(s, sz, "%02X", ((unsigned char*)l->data)[n]);
+ if (r < 0 || r >= sz) {
+ printf("Context Specific boom");
+ exit(EXIT_FAILURE);
+ }
+ s += r;
+ sz -= r;
+ }
+ text = buf;
+ }
+ break;
+ }
+
+ for (n = 0; n < level; ++n) {
+ fprintf(stderr, " ");
+ }
+ if (name) {
+ if (text)
+ fprintf(stderr, "%s %s\n", name, text);
+ else
+ fprintf(stderr, "%s <missing decoding>\n", name);
+ }
+ else
+ fprintf(stderr, "WTF type=%i\n", l->type);
+
+ if (ostring) {
+ _der_tests_print_flexi(ostring, level + 1);
+ der_free_sequence_flexi(ostring);
+ }
+
+ if (l->child)
+ _der_tests_print_flexi(l->child, level + 1);
+
+ if (l->next)
+ _der_tests_print_flexi(l->next, level);
+}
+#endif
+
+static void der_cacert_test(void)
+{
+ unsigned char buf[sizeof(_der_tests_cacert_root_cert)];
+ unsigned long len1 = sizeof(buf), len2;
+
+ ltc_asn1_list *decoded_list, *l, *l1, *l2;
+
+ DO(base64_decode(_der_tests_stinky_root_cert, sizeof(_der_tests_stinky_root_cert), buf, &len1));
+ len2 = len1;
+ DO(der_decode_sequence_flexi(buf, &len2, &decoded_list));
+ der_free_sequence_flexi(decoded_list);
+
+ len1 = sizeof(buf);
+ DO(base64_decode(_der_tests_cacert_root_cert, sizeof(_der_tests_cacert_root_cert), buf, &len1));
+ len2 = len1;
+ DO(der_decode_sequence_flexi(buf, &len2, &decoded_list));
+ CHECK_ASN1_TYPE(decoded_list, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_DATA(decoded_list);
+
+ der_sequence_shrink(decoded_list);
+
+ CHECK_ASN1_TYPE(decoded_list, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_NO_DATA(decoded_list);
+
+#ifdef LTC_DER_TESTS_PRINT_FLEXI
+ printf("\n\n--- test print start ---\n\n");
+ _der_tests_print_flexi(decoded_list, 0);
+ printf("\n\n--- test print end ---\n\n");
+#endif
+
+ l = decoded_list;
+
+ /*
+SEQUENCE(3 elem)
+ SEQUENCE(8 elem)
+ */
+
+ CHECK_ASN1_TYPE(l, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_CHILD(l);
+ CHECK_ASN1_HAS_NO_NEXT(l);
+
+ l = l->child;
+
+ CHECK_ASN1_TYPE(l, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_CHILD(l);
+ CHECK_ASN1_HAS_NEXT(l);
+
+ l1 = l->child;
+
+ /*
+ [0](1)
+ INTEGER 2
+ */
+
+ CHECK_ASN1_TYPE(l1, LTC_ASN1_CONSTRUCTED);
+ CHECK_ASN1_HAS_CHILD(l1);
+ CHECK_ASN1_HAS_NEXT(l1);
+
+ l2 = l1->child;
+
+ CHECK_ASN1_TYPE(l2, LTC_ASN1_INTEGER);
+ CHECK_ASN1_HAS_NO_CHILD(l2);
+ CHECK_ASN1_HAS_NO_NEXT(l2);
+
+ l1 = l1->next;
+
+ /*
+ INTEGER 0
+ */
+
+ CHECK_ASN1_TYPE(l1, LTC_ASN1_INTEGER);
+ CHECK_ASN1_HAS_NO_CHILD(l1);
+ CHECK_ASN1_HAS_NEXT(l1);
+
+ l1 = l1->next;
+
+ /*
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.1.4
+ NULL
+ */
+
+ CHECK_ASN1_TYPE(l1, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_CHILD(l1);
+ CHECK_ASN1_HAS_NEXT(l1);
+
+ l2 = l1->child;
+
+ CHECK_ASN1_TYPE(l2, LTC_ASN1_OBJECT_IDENTIFIER);
+ CHECK_ASN1_HAS_NO_CHILD(l2);
+ CHECK_ASN1_HAS_NEXT(l2);
+
+ l2 = l2->next;
+
+ CHECK_ASN1_TYPE(l2, LTC_ASN1_NULL);
+ CHECK_ASN1_HAS_NO_CHILD(l2);
+ CHECK_ASN1_HAS_NO_NEXT(l2);
+
+ /*
+ SEQUENCE(4 elem)
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.10
+ PrintableString Root CA
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.11
+ PrintableString http://www.cacert.org
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 2.5.4.3
+ PrintableString CA Cert Signing Authority
+ SET(1 elem)
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.9.1
+ IA5String support@cacert.org
+ */
+
+ l = l->next;
+
+ /*
+ SEQUENCE(2 elem)
+ OBJECT IDENTIFIER 1.2.840.113549.1.1.4
+ NULL
+ */
+
+ CHECK_ASN1_TYPE(l, LTC_ASN1_SEQUENCE);
+ CHECK_ASN1_HAS_CHILD(l);
+ CHECK_ASN1_HAS_NEXT(l);
+
+ l1 = l->child;
+
+ CHECK_ASN1_TYPE(l1, LTC_ASN1_OBJECT_IDENTIFIER);
+ CHECK_ASN1_HAS_NO_CHILD(l1);
+ CHECK_ASN1_HAS_NEXT(l1);
+
+ l1 = l1->next;
+
+ CHECK_ASN1_TYPE(l1, LTC_ASN1_NULL);
+ CHECK_ASN1_HAS_NO_CHILD(l1);
+ CHECK_ASN1_HAS_NO_NEXT(l1);
+
+ l = l->next;
+
+ /*
+ BIT STRING(4096 bit)
+ */
+
+ CHECK_ASN1_TYPE(l, LTC_ASN1_BIT_STRING);
+ CHECK_ASN1_HAS_NO_CHILD(l);
+ CHECK_ASN1_HAS_NO_NEXT(l);
+
+ der_free_sequence_flexi(decoded_list);
+}
+
+static void der_set_test(void)
+{
+ ltc_asn1_list list[10];
+ static const unsigned char oct_str[] = { 1, 2, 3, 4 };
+ static const unsigned char bin_str[] = { 1, 0, 0, 1 };
+ static const unsigned long int_val = 12345678UL;
+
+ unsigned char strs[10][10], outbuf[128];
+ unsigned long x, val, outlen;
+
+ /* make structure and encode it */
+ LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING, oct_str, sizeof(oct_str));
+ LTC_SET_ASN1(list, 1, LTC_ASN1_BIT_STRING, bin_str, sizeof(bin_str));
+ LTC_SET_ASN1(list, 2, LTC_ASN1_SHORT_INTEGER, &int_val, 1);
+
+ /* encode it */
+ outlen = sizeof(outbuf);
+ DO(der_encode_set(list, 3, outbuf, &outlen));
+
+ /* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */
+ LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING, strs[1], sizeof(strs[1]));
+ LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1);
+ LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING, strs[0], sizeof(strs[0]));
+
+ DO(der_decode_set(outbuf, outlen, list, 3));
+
+ /* now compare the items */
+ if (memcmp(strs[0], oct_str, sizeof(oct_str))) {
+ fprintf(stderr, "error decoding set using der_decode_set (oct_str is wrong):\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (memcmp(strs[1], bin_str, sizeof(bin_str))) {
+ fprintf(stderr, "error decoding set using der_decode_set (bin_str is wrong):\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (val != int_val) {
+ fprintf(stderr, "error decoding set using der_decode_set (int_val is wrong):\n");
+ exit(EXIT_FAILURE);
+ }
+
+ strcpy((char*)strs[0], "one");
+ strcpy((char*)strs[1], "one2");
+ strcpy((char*)strs[2], "two");
+ strcpy((char*)strs[3], "aaa");
+ strcpy((char*)strs[4], "aaaa");
+ strcpy((char*)strs[5], "aab");
+ strcpy((char*)strs[6], "aaab");
+ strcpy((char*)strs[7], "bbb");
+ strcpy((char*)strs[8], "bbba");
+ strcpy((char*)strs[9], "bbbb");
+
+ for (x = 0; x < 10; x++) {
+ LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen((char*)strs[x]));
+ }
+
+ outlen = sizeof(outbuf);
+ DO(der_encode_setof(list, 10, outbuf, &outlen));
+
+ for (x = 0; x < 10; x++) {
+ LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1);
+ }
+ XMEMSET(strs, 0, sizeof(strs));
+
+ DO(der_decode_set(outbuf, outlen, list, 10));
+
+ /* now compare */
+ for (x = 1; x < 10; x++) {
+ if (!(strlen((char*)strs[x-1]) <= strlen((char*)strs[x])) && strcmp((char*)strs[x-1], (char*)strs[x]) >= 0) {
+ fprintf(stderr, "error SET OF order at %lu is wrong\n", x);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+}
+
+
+/* we are encoding
+
+ SEQUENCE {
+ PRINTABLE "printable"
+ IA5 "ia5"
+ SEQUENCE {
+ INTEGER 12345678
+ UTCTIME { 91, 5, 6, 16, 45, 40, 1, 7, 0 }
+ GENERALIZEDTIME { 2017, 03, 21, 10, 21, 12, 4, 1, 2, 0 }
+ SEQUENCE {
+ OCTET STRING { 1, 2, 3, 4 }
+ BIT STRING { 1, 0, 0, 1 }
+ SEQUENCE {
+ OID { 1, 2, 840, 113549 }
+ NULL
+ SET OF {
+ PRINTABLE "333" -- WILL GET SORTED
+ PRINTABLE "222"
+ }
+ }
+ }
+ }
+
+*/
+
+static void der_flexi_test(void)
+{
+ static const char printable_str[] = "printable";
+ static const char set1_str[] = "333";
+ static const char set2_str[] = "222";
+ static const char ia5_str[] = "ia5";
+ static const unsigned long int_val = 12345678UL;
+ static const ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
+ static const ltc_generalizedtime gtime = { 2017, 03, 21, 10, 21, 12, 421, 1, 2, 0 };
+ static const unsigned char oct_str[] = { 1, 2, 3, 4 };
+ static const unsigned char bit_str[] = { 1, 0, 0, 1 };
+ static const unsigned long oid_str[] = { 1, 2, 840, 113549 };
+
+ unsigned char encode_buf[192];
+ unsigned long encode_buf_len, decode_len;
+
+ ltc_asn1_list static_list[5][4], *decoded_list, *l;
+
+ /* build list */
+ LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str));
+ LTC_SET_ASN1(static_list[0], 1, LTC_ASN1_IA5_STRING, (void *)ia5_str, strlen(ia5_str));
+ LTC_SET_ASN1(static_list[0], 2, LTC_ASN1_SEQUENCE, static_list[1], 4);
+
+ LTC_SET_ASN1(static_list[1], 0, LTC_ASN1_SHORT_INTEGER, (void *)&int_val, 1);
+ LTC_SET_ASN1(static_list[1], 1, LTC_ASN1_UTCTIME, (void *)&utctime, 1);
+ LTC_SET_ASN1(static_list[1], 2, LTC_ASN1_GENERALIZEDTIME, (void *)&gtime, 1);
+ LTC_SET_ASN1(static_list[1], 3, LTC_ASN1_SEQUENCE, static_list[2], 3);
+
+ LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING, (void *)oct_str, 4);
+ LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING, (void *)bit_str, 4);
+ LTC_SET_ASN1(static_list[2], 2, LTC_ASN1_SEQUENCE, static_list[3], 3);
+
+ LTC_SET_ASN1(static_list[3], 0, LTC_ASN1_OBJECT_IDENTIFIER,(void *)oid_str, 4);
+ LTC_SET_ASN1(static_list[3], 1, LTC_ASN1_NULL, NULL, 0);
+ LTC_SET_ASN1(static_list[3], 2, LTC_ASN1_SETOF, static_list[4], 2);
+
+ LTC_SET_ASN1(static_list[4], 0, LTC_ASN1_PRINTABLE_STRING, set1_str, strlen(set1_str));
+ LTC_SET_ASN1(static_list[4], 1, LTC_ASN1_PRINTABLE_STRING, set2_str, strlen(set2_str));
+
+ /* encode it */
+ encode_buf_len = sizeof(encode_buf);
+ DO(der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len));
+
+#if 0
+ {
+ FILE *f;
+ f = fopen("t.bin", "wb");
+ fwrite(encode_buf, 1, encode_buf_len, f);
+ fclose(f);
+ }
+#endif
+
+ /* decode with flexi */
+ decode_len = encode_buf_len;
+ DO(der_decode_sequence_flexi(encode_buf, &decode_len, &decoded_list));
+
+ if (decode_len != encode_buf_len) {
+ fprintf(stderr, "Decode len of %lu does not match encode len of %lu \n", decode_len, encode_buf_len);
+ exit(EXIT_FAILURE);
+ }
+
+ /* we expect l->next to be NULL and l->child to not be */
+ l = decoded_list;
+ if (l->next != NULL || l->child == NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* we expect a SEQUENCE */
+ if (l->type != LTC_ASN1_SEQUENCE) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+ l = l->child;
+
+ /* PRINTABLE STRING */
+ /* we expect printable_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_PRINTABLE_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != strlen(printable_str) || memcmp(printable_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* IA5 STRING */
+ /* we expect ia5_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_IA5_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != strlen(ia5_str) || memcmp(ia5_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* expect child anve move down */
+
+ if (l->next != NULL || l->child == NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_SEQUENCE) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+ l = l->child;
+
+
+ /* INTEGER */
+
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_INTEGER) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (mp_cmp_d(l->data, 12345678UL) != LTC_MP_EQ) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* UTCTIME */
+
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_UTCTIME) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (memcmp(l->data, &utctime, sizeof(utctime))) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* GeneralizedTime */
+
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_GENERALIZEDTIME) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (memcmp(l->data, &gtime, sizeof(gtime))) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* expect child anve move down */
+
+ if (l->next != NULL || l->child == NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_SEQUENCE) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+ l = l->child;
+
+
+ /* OCTET STRING */
+ /* we expect oct_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_OCTET_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != sizeof(oct_str) || memcmp(oct_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* BIT STRING */
+ /* we expect oct_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_BIT_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != sizeof(bit_str) || memcmp(bit_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* expect child anve move down */
+
+ if (l->next != NULL || l->child == NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_SEQUENCE) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+ l = l->child;
+
+
+ /* OID STRING */
+ /* we expect oid_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != sizeof(oid_str)/sizeof(oid_str[0]) || memcmp(oid_str, l->data, l->size*sizeof(oid_str[0]))) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* NULL */
+ if (l->type != LTC_ASN1_NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* expect child anve move down */
+ if (l->next != NULL || l->child == NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_SET) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+ l = l->child;
+
+ /* PRINTABLE STRING */
+ /* we expect printable_str */
+ if (l->next == NULL || l->child != NULL) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->type != LTC_ASN1_PRINTABLE_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+/* note we compare set2_str FIRST because the SET OF is sorted and "222" comes before "333" */
+ if (l->size != strlen(set2_str) || memcmp(set2_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ /* move to next */
+ l = l->next;
+
+ /* PRINTABLE STRING */
+ /* we expect printable_str */
+ if (l->type != LTC_ASN1_PRINTABLE_STRING) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+ if (l->size != strlen(set1_str) || memcmp(set1_str, l->data, l->size)) {
+ fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+ exit(EXIT_FAILURE);
+ }
+
+
+ der_sequence_free(l);
+
+}
+
+static int der_choice_test(void)
+{
+ ltc_asn1_list types[7], host[1];
+ unsigned char bitbuf[10], octetbuf[10], ia5buf[10], printbuf[10], outbuf[256], x, y;
+ unsigned long integer, oidbuf[10], outlen, inlen;
+ void *mpinteger;
+ ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
+ ltc_generalizedtime gtime = { 2038, 01, 19, 3, 14, 8, 0, 0, 0, 0 };
+
+ /* setup variables */
+ for (x = 0; x < sizeof(bitbuf); x++) { bitbuf[x] = x & 1; }
+ for (x = 0; x < sizeof(octetbuf); x++) { octetbuf[x] = x; }
+ for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; }
+ for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; }
+ integer = 1;
+ for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; }
+ DO(mp_init(&mpinteger));
+
+ for (x = 0; x < 14; x++) {
+ /* setup list */
+ LTC_SET_ASN1(types, 0, LTC_ASN1_PRINTABLE_STRING, printbuf, sizeof(printbuf));
+ LTC_SET_ASN1(types, 1, LTC_ASN1_BIT_STRING, bitbuf, sizeof(bitbuf));
+ LTC_SET_ASN1(types, 2, LTC_ASN1_OCTET_STRING, octetbuf, sizeof(octetbuf));
+ LTC_SET_ASN1(types, 3, LTC_ASN1_IA5_STRING, ia5buf, sizeof(ia5buf));
+ if (x > 7) {
+ LTC_SET_ASN1(types, 4, LTC_ASN1_SHORT_INTEGER, &integer, 1);
+ } else {
+ LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, mpinteger, 1);
+ }
+ LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0]));
+ if (x > 7) {
+ LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1);
+ } else {
+ LTC_SET_ASN1(types, 6, LTC_ASN1_GENERALIZEDTIME, &gtime, 1);
+ }
+
+ LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7);
+
+
+ /* encode */
+ outlen = sizeof(outbuf);
+ DO(der_encode_sequence(&types[x>6?x-7:x], 1, outbuf, &outlen));
+
+ /* decode it */
+ inlen = outlen;
+ DO(der_decode_sequence(outbuf, inlen, &host[0], 1));
+
+ for (y = 0; y < 7; y++) {
+ if (types[y].used && y != (x>6?x-7:x)) {
+ fprintf(stderr, "CHOICE, flag %u in trial %u was incorrectly set to one\n", y, x);
+ return 1;
+ }
+ if (!types[y].used && y == (x>6?x-7:x)) {
+ fprintf(stderr, "CHOICE, flag %u in trial %u was incorrectly set to zero\n", y, x);
+ return 1;
+ }
+ }
+ }
+ mp_clear(mpinteger);
+ return 0;
+}
+
+
+int der_test(void)
+{
+ unsigned long x, y, z, zz, oid[2][32];
+ unsigned char buf[3][2048];
+ void *a, *b, *c, *d, *e, *f, *g;
+
+ static const unsigned char rsa_oid_der[] = { 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d };
+ static const unsigned long rsa_oid[] = { 1, 2, 840, 113549 };
+
+ static const unsigned char rsa_ia5[] = "test1@rsa.com";
+ static const unsigned char rsa_ia5_der[] = { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31,
+ 0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d };
+
+ static const unsigned char rsa_printable[] = "Test User 1";
+ static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55,
+ 0x73, 0x65, 0x72, 0x20, 0x31 };
+
+ static const ltc_utctime rsa_time1 = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
+ static const ltc_utctime rsa_time2 = { 91, 5, 6, 23, 45, 40, 0, 0, 0 };
+ ltc_utctime tmp_time;
+
+ static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 };
+ static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a };
+
+ static const wchar_t utf8_1[] = { 0x0041, 0x2262, 0x0391, 0x002E };
+ static const unsigned char utf8_1_der[] = { 0x0C, 0x07, 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E };
+ static const wchar_t utf8_2[] = { 0xD55C, 0xAD6D, 0xC5B4 };
+ static const unsigned char utf8_2_der[] = { 0x0C, 0x09, 0xED, 0x95, 0x9C, 0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4 };
+
+ unsigned char utf8_buf[32];
+ wchar_t utf8_out[32];
+
+ der_cacert_test();
+
+ DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));
+ for (zz = 0; zz < 16; zz++) {
+#ifdef USE_TFM
+ for (z = 0; z < 256; z++) {
+#else
+ for (z = 0; z < 1024; z++) {
+#endif
+ if (yarrow_read(buf[0], z, &yarrow_prng) != z) {
+ fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z);
+ return 1;
+ }
+ DO(mp_read_unsigned_bin(a, buf[0], z));
+/* if (mp_iszero(a) == LTC_MP_NO) { a.sign = buf[0][0] & 1 ? LTC_MP_ZPOS : LTC_MP_NEG; } */
+ x = sizeof(buf[0]);
+ DO(der_encode_integer(a, buf[0], &x));
+ DO(der_length_integer(a, &y));
+ if (y != x) { fprintf(stderr, "DER INTEGER size mismatch\n"); return 1; }
+ mp_set_int(b, 0);
+ DO(der_decode_integer(buf[0], y, b));
+ if (y != x || mp_cmp(a, b) != LTC_MP_EQ) {
+ fprintf(stderr, "%lu: %lu vs %lu\n", z, x, y);
+ mp_clear_multi(a, b, c, d, e, f, g, NULL);
+ return 1;
+ }
+ }
+ }
+
+/* test short integer */
+ for (zz = 0; zz < 256; zz++) {
+ for (z = 1; z < 4; z++) {
+ if (yarrow_read(buf[2], z, &yarrow_prng) != z) {
+ fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z);
+ return 1;
+ }
+ /* encode with normal */
+ DO(mp_read_unsigned_bin(a, buf[2], z));
+
+ x = sizeof(buf[0]);
+ DO(der_encode_integer(a, buf[0], &x));
+
+ /* encode with short */
+ y = sizeof(buf[1]);
+ DO(der_encode_short_integer(mp_get_int(a), buf[1], &y));
+ if (x != y || memcmp(buf[0], buf[1], x)) {
+ fprintf(stderr, "DER INTEGER short encoding failed, %lu, %lu, 0x%lX\n", x, y, mp_get_int(a));
+ for (zz = 0; zz < z; zz++) fprintf(stderr, "%02x ", buf[2][zz]);
+ fprintf(stderr, "\n");
+ for (z = 0; z < x; z++) fprintf(stderr, "%02x ", buf[0][z]);
+ fprintf(stderr, "\n");
+ for (z = 0; z < y; z++) fprintf(stderr, "%02x ", buf[1][z]);
+ fprintf(stderr, "\n");
+ mp_clear_multi(a, b, c, d, e, f, g, NULL);
+ return 1;
+ }
+
+ /* decode it */
+ x = 0;
+ DO(der_decode_short_integer(buf[1], y, &x));
+ if (x != mp_get_int(a)) {
+ fprintf(stderr, "DER INTEGER short decoding failed, %lu, %lu\n", x, mp_get_int(a));
+ mp_clear_multi(a, b, c, d, e, f, g, NULL);
+ return 1;
+ }
+ }
+ }
+ mp_clear_multi(a, b, c, d, e, f, g, NULL);
+
+
+/* Test bit string */
+ for (zz = 1; zz < 1536; zz++) {
+ yarrow_read(buf[0], zz, &yarrow_prng);
+ for (z = 0; z < zz; z++) {
+ buf[0][z] &= 0x01;
+ }
+ x = sizeof(buf[1]);
+ DO(der_encode_bit_string(buf[0], zz, buf[1], &x));
+ DO(der_length_bit_string(zz, &y));
+ if (y != x) {
+ fprintf(stderr, "\nDER BIT STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y);
+ return 1;
+ }
+
+ y = sizeof(buf[2]);
+ DO(der_decode_bit_string(buf[1], x, buf[2], &y));
+ if (y != zz || memcmp(buf[0], buf[2], zz)) {
+ fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz));
+ return 1;
+ }
+ }
+
+/* Test octet string */
+ for (zz = 1; zz < 1536; zz++) {
+ yarrow_read(buf[0], zz, &yarrow_prng);
+ x = sizeof(buf[1]);
+ DO(der_encode_octet_string(buf[0], zz, buf[1], &x));
+ DO(der_length_octet_string(zz, &y));
+ if (y != x) {
+ fprintf(stderr, "\nDER OCTET STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y);
+ return 1;
+ }
+ y = sizeof(buf[2]);
+ DO(der_decode_octet_string(buf[1], x, buf[2], &y));
+ if (y != zz || memcmp(buf[0], buf[2], zz)) {
+ fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz));
+ return 1;
+ }
+ }
+
+/* test OID */
+ x = sizeof(buf[0]);
+ DO(der_encode_object_identifier((unsigned long*)rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x));
+ if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) {
+ fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x);
+ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+ y = sizeof(oid[0])/sizeof(oid[0][0]);
+ DO(der_decode_object_identifier(buf[0], x, oid[0], &y));
+ if (y != sizeof(rsa_oid)/sizeof(rsa_oid[0]) || memcmp(rsa_oid, oid[0], sizeof(rsa_oid))) {
+ fprintf(stderr, "rsa_oid_der decode failed to match, %lu, ", y);
+ for (z = 0; z < y; z++) fprintf(stderr, "%lu ", oid[0][z]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+ /* do random strings */
+ for (zz = 0; zz < 5000; zz++) {
+ /* pick a random number of words */
+ yarrow_read(buf[0], 4, &yarrow_prng);
+ LOAD32L(z, buf[0]);
+ z = 2 + (z % ((sizeof(oid[0])/sizeof(oid[0][0])) - 2));
+
+ /* fill them in */
+ oid[0][0] = buf[0][0] % 3;
+ oid[0][1] = buf[0][1] % 40;
+
+ for (y = 2; y < z; y++) {
+ yarrow_read(buf[0], 4, &yarrow_prng);
+ LOAD32L(oid[0][y], buf[0]);
+ }
+
+ /* encode it */
+ x = sizeof(buf[0]);
+ DO(der_encode_object_identifier(oid[0], z, buf[0], &x));
+ DO(der_length_object_identifier(oid[0], z, &y));
+ if (x != y) {
+ fprintf(stderr, "Random OID %lu test failed, length mismatch: %lu, %lu\n", z, x, y);
+ for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]);
+ return 1;
+ }
+
+ /* decode it */
+ y = sizeof(oid[0])/sizeof(oid[0][0]);
+ DO(der_decode_object_identifier(buf[0], x, oid[1], &y));
+ if (y != z) {
+ fprintf(stderr, "Random OID %lu test failed, decode length mismatch: %lu, %lu\n", z, x, y);
+ return 1;
+ }
+ if (memcmp(oid[0], oid[1], sizeof(oid[0][0]) * z)) {
+ fprintf(stderr, "Random OID %lu test failed, decoded values wrong\n", z);
+ for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]);
+ fprintf(stderr, "\n\n Got \n\n");
+ for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[1][x]);
+ return 1;
+ }
+ }
+
+/* IA5 string */
+ x = sizeof(buf[0]);
+ DO(der_encode_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), buf[0], &x));
+ if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) {
+ fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der));
+ return 1;
+ }
+ DO(der_length_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), &y));
+ if (y != x) {
+ fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y);
+ return 1;
+ }
+ y = sizeof(buf[1]);
+ DO(der_decode_ia5_string(buf[0], x, buf[1], &y));
+ if (y != strlen((char*)rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen((char*)rsa_ia5))) {
+ fprintf(stderr, "DER IA5 failed test vector\n");
+ return 1;
+ }
+
+/* Printable string */
+ x = sizeof(buf[0]);
+ DO(der_encode_printable_string(rsa_printable, strlen((char*)rsa_printable), buf[0], &x));
+ if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) {
+ fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der));
+ return 1;
+ }
+ DO(der_length_printable_string(rsa_printable, strlen((char*)rsa_printable), &y));
+ if (y != x) {
+ fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y);
+ return 1;
+ }
+ y = sizeof(buf[1]);
+ DO(der_decode_printable_string(buf[0], x, buf[1], &y));
+ if (y != strlen((char*)rsa_printable) || memcmp(buf[1], rsa_printable, strlen((char*)rsa_printable))) {
+ fprintf(stderr, "DER printable failed test vector\n");
+ return 1;
+ }
+
+/* Test UTC time */
+ x = sizeof(buf[0]);
+ DO(der_encode_utctime((ltc_utctime*)&rsa_time1, buf[0], &x));
+ if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) {
+ fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
+ fprintf(stderr, "\n\n");
+ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ DO(der_length_utctime((ltc_utctime*)&rsa_time1, &y));
+ if (y != x) {
+ fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y);
+ return 1;
+ }
+ DO(der_decode_utctime(buf[0], &y, &tmp_time));
+ if (y != x || memcmp(&rsa_time1, &tmp_time, sizeof(ltc_utctime))) {
+ fprintf(stderr, "UTCTIME decode failed for rsa_time1: %lu %lu\n", x, y);
+fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n",
+tmp_time.YY,
+tmp_time.MM,
+tmp_time.DD,
+tmp_time.hh,
+tmp_time.mm,
+tmp_time.ss,
+tmp_time.off_dir,
+tmp_time.off_mm,
+tmp_time.off_hh);
+ return 1;
+ }
+
+ x = sizeof(buf[0]);
+ DO(der_encode_utctime((ltc_utctime*)&rsa_time2, buf[0], &x));
+ if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) {
+ fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
+ fprintf(stderr, "\n\n");
+ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ DO(der_length_utctime((ltc_utctime*)&rsa_time2, &y));
+ if (y != x) {
+ fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y);
+ return 1;
+ }
+ DO(der_decode_utctime(buf[0], &y, &tmp_time));
+ if (y != x || memcmp(&rsa_time2, &tmp_time, sizeof(ltc_utctime))) {
+ fprintf(stderr, "UTCTIME decode failed for rsa_time2: %lu %lu\n", x, y);
+fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n",
+tmp_time.YY,
+tmp_time.MM,
+tmp_time.DD,
+tmp_time.hh,
+tmp_time.mm,
+tmp_time.ss,
+tmp_time.off_dir,
+tmp_time.off_mm,
+tmp_time.off_hh);
+
+
+ return 1;
+ }
+
+ /* UTF 8 */
+ /* encode it */
+ x = sizeof(utf8_buf);
+ DO(der_encode_utf8_string(utf8_1, sizeof(utf8_1) / sizeof(utf8_1[0]), utf8_buf, &x));
+ DO(der_length_utf8_string(utf8_1, sizeof(utf8_1) / sizeof(utf8_1[0]), &y));
+ if (x != sizeof(utf8_1_der) || memcmp(utf8_buf, utf8_1_der, x) || x != y) {
+ fprintf(stderr, "DER UTF8_1 encoded to %lu bytes\n", x);
+ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ /* decode it */
+ y = sizeof(utf8_out) / sizeof(utf8_out[0]);
+ DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y));
+ if (y != (sizeof(utf8_1) / sizeof(utf8_1[0])) || memcmp(utf8_1, utf8_out, y * sizeof(wchar_t))) {
+ fprintf(stderr, "DER UTF8_1 decoded to %lu wchar_t\n", y);
+ for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+ /* encode it */
+ x = sizeof(utf8_buf);
+ DO(der_encode_utf8_string(utf8_2, sizeof(utf8_2) / sizeof(utf8_2[0]), utf8_buf, &x));
+ if (x != sizeof(utf8_2_der) || memcmp(utf8_buf, utf8_2_der, x)) {
+ fprintf(stderr, "DER UTF8_2 encoded to %lu bytes\n", x);
+ for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ /* decode it */
+ y = sizeof(utf8_out) / sizeof(utf8_out[0]);
+ DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y));
+ if (y != (sizeof(utf8_2) / sizeof(utf8_2[0])) || memcmp(utf8_2, utf8_out, y * sizeof(wchar_t))) {
+ fprintf(stderr, "DER UTF8_2 decoded to %lu wchar_t\n", y);
+ for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+
+
+ der_set_test();
+ der_flexi_test();
+ return der_choice_test();
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/dh_test.c b/libtomcrypt/tests/dh_test.c
new file mode 100644
index 0000000..5feca21
--- /dev/null
+++ b/libtomcrypt/tests/dh_test.c
@@ -0,0 +1,454 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MDH) && defined(LTC_TEST_MPI)
+
+#ifdef LTC_DH4096
+#define KEYSIZE 4096
+#else
+#define KEYSIZE 2048
+#endif
+
+static int _prime_test(void)
+{
+ void *p, *g, *tmp;
+ int x, err, primality;
+
+ if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != CRYPT_OK) { goto error; }
+
+ for (x = 0; ltc_dh_sets[x].size != 0; x++) {
+ if ((err = mp_read_radix(g, ltc_dh_sets[x].base, 16)) != CRYPT_OK) { goto error; }
+ if ((err = mp_read_radix(p, ltc_dh_sets[x].prime, 16)) != CRYPT_OK) { goto error; }
+
+ /* ensure p is prime */
+ if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; }
+ if (primality != LTC_MP_YES ) {
+ err = CRYPT_FAIL_TESTVECTOR;
+ goto done;
+ }
+
+ if ((err = mp_sub_d(p, 1, tmp)) != CRYPT_OK) { goto error; }
+ if ((err = mp_div_2(tmp, tmp)) != CRYPT_OK) { goto error; }
+
+ /* ensure (p-1)/2 is prime */
+ if ((err = mp_prime_is_prime(tmp, 8, &primality)) != CRYPT_OK) { goto done; }
+ if (primality == 0) {
+ err = CRYPT_FAIL_TESTVECTOR;
+ goto done;
+ }
+
+ /* now see if g^((p-1)/2) mod p is in fact 1 */
+ if ((err = mp_exptmod(g, tmp, p, tmp)) != CRYPT_OK) { goto error; }
+ if (mp_cmp_d(tmp, 1)) {
+ err = CRYPT_FAIL_TESTVECTOR;
+ goto done;
+ }
+ }
+ err = CRYPT_OK;
+error:
+done:
+ mp_clear_multi(tmp, g, p, NULL);
+ return err;
+}
+
+static int _dhparam_test(void)
+{
+ dh_key k;
+ unsigned char buf[1024];
+ /* generated by: openssl dhparam -outform der -out dhparam.der 2048 */
+ unsigned char dhparam_der[] = {
+ 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0xfe, 0x78, 0xce, 0x80, 0xd5, 0xd7,
+ 0x8e, 0xcc, 0x4f, 0x0c, 0x1b, 0xb0, 0x95, 0x10, 0xe1, 0x41, 0x15, 0x53, 0x4d, 0x0e, 0x68, 0xb0,
+ 0xf8, 0x5a, 0x41, 0x0e, 0x65, 0x2f, 0x9f, 0xac, 0x9c, 0x30, 0xb0, 0x76, 0xec, 0x02, 0xe9, 0x43,
+ 0x55, 0x08, 0xb4, 0x20, 0x60, 0xd9, 0x52, 0xda, 0x2d, 0xab, 0x9a, 0xba, 0xe6, 0xcf, 0x11, 0xa7,
+ 0x00, 0x44, 0xc2, 0x5e, 0xd1, 0xba, 0x9b, 0xaa, 0xfe, 0x03, 0xdd, 0xdc, 0xef, 0x41, 0x89, 0x9c,
+ 0xac, 0x64, 0x13, 0xd9, 0x6a, 0x8a, 0x55, 0xa0, 0x5b, 0xff, 0x12, 0x92, 0x37, 0x52, 0x6a, 0x91,
+ 0xa4, 0x6e, 0x9e, 0x61, 0xb7, 0xfe, 0xb0, 0x17, 0x8e, 0x67, 0x0f, 0x88, 0x46, 0xa7, 0x9e, 0xb1,
+ 0xdb, 0x68, 0x77, 0x70, 0xb5, 0x77, 0xf2, 0x7e, 0x33, 0xb1, 0x3e, 0x10, 0xc4, 0x63, 0x36, 0xd0,
+ 0x13, 0x27, 0xd3, 0x29, 0xc3, 0xb6, 0x5d, 0xf6, 0x5d, 0xa7, 0xd8, 0x25, 0x5c, 0x0b, 0x65, 0x99,
+ 0xfa, 0xf9, 0x5f, 0x1d, 0xee, 0xd1, 0x86, 0x64, 0x7c, 0x44, 0xcb, 0xa0, 0x12, 0x52, 0x4c, 0xd4,
+ 0x46, 0x81, 0xae, 0x07, 0xdb, 0xc7, 0x13, 0x29, 0xce, 0x9b, 0xcf, 0x1c, 0x06, 0xd2, 0x0f, 0x2d,
+ 0xbb, 0x12, 0x33, 0xb9, 0xb1, 0x0f, 0x67, 0x5d, 0x3f, 0x0c, 0xe4, 0xfa, 0x67, 0x26, 0xe2, 0x89,
+ 0xa2, 0xd5, 0x66, 0x29, 0x1c, 0xe2, 0x8e, 0xbb, 0x7b, 0xcb, 0xcc, 0x70, 0x7e, 0x4f, 0x0e, 0xd3,
+ 0x5d, 0x64, 0x64, 0x1b, 0x27, 0xbb, 0xda, 0xa9, 0x08, 0x2b, 0x62, 0xd4, 0xca, 0xc3, 0x3a, 0x23,
+ 0x39, 0x58, 0x57, 0xaf, 0x7b, 0x8b, 0x0c, 0x5b, 0x2e, 0xfc, 0x42, 0x57, 0x59, 0x39, 0x2e, 0x6d,
+ 0x39, 0x97, 0xdb, 0x5b, 0x5c, 0xb9, 0x59, 0x71, 0x42, 0xf3, 0xcd, 0xea, 0xda, 0x86, 0x54, 0x86,
+ 0x61, 0x8d, 0x93, 0x66, 0xc7, 0x65, 0xd1, 0x98, 0xcb, 0x02, 0x01, 0x02
+ };
+ /* text dump: openssl dh -inform DER -in dhparam.der -text
+ DH Parameters: (2048 bit)
+ prime:
+ 00:ae:fe:78:ce:80:d5:d7:8e:cc:4f:0c:1b:b0:95:
+ 10:e1:41:15:53:4d:0e:68:b0:f8:5a:41:0e:65:2f:
+ 9f:ac:9c:30:b0:76:ec:02:e9:43:55:08:b4:20:60:
+ d9:52:da:2d:ab:9a:ba:e6:cf:11:a7:00:44:c2:5e:
+ d1:ba:9b:aa:fe:03:dd:dc:ef:41:89:9c:ac:64:13:
+ d9:6a:8a:55:a0:5b:ff:12:92:37:52:6a:91:a4:6e:
+ 9e:61:b7:fe:b0:17:8e:67:0f:88:46:a7:9e:b1:db:
+ 68:77:70:b5:77:f2:7e:33:b1:3e:10:c4:63:36:d0:
+ 13:27:d3:29:c3:b6:5d:f6:5d:a7:d8:25:5c:0b:65:
+ 99:fa:f9:5f:1d:ee:d1:86:64:7c:44:cb:a0:12:52:
+ 4c:d4:46:81:ae:07:db:c7:13:29:ce:9b:cf:1c:06:
+ d2:0f:2d:bb:12:33:b9:b1:0f:67:5d:3f:0c:e4:fa:
+ 67:26:e2:89:a2:d5:66:29:1c:e2:8e:bb:7b:cb:cc:
+ 70:7e:4f:0e:d3:5d:64:64:1b:27:bb:da:a9:08:2b:
+ 62:d4:ca:c3:3a:23:39:58:57:af:7b:8b:0c:5b:2e:
+ fc:42:57:59:39:2e:6d:39:97:db:5b:5c:b9:59:71:
+ 42:f3:cd:ea:da:86:54:86:61:8d:93:66:c7:65:d1:
+ 98:cb
+ generator: 2 (0x2)
+ */
+ unsigned char prime[] = {
+ 0xae, 0xfe, 0x78, 0xce, 0x80, 0xd5, 0xd7, 0x8e, 0xcc, 0x4f, 0x0c, 0x1b, 0xb0, 0x95,
+ 0x10, 0xe1, 0x41, 0x15, 0x53, 0x4d, 0x0e, 0x68, 0xb0, 0xf8, 0x5a, 0x41, 0x0e, 0x65, 0x2f,
+ 0x9f, 0xac, 0x9c, 0x30, 0xb0, 0x76, 0xec, 0x02, 0xe9, 0x43, 0x55, 0x08, 0xb4, 0x20, 0x60,
+ 0xd9, 0x52, 0xda, 0x2d, 0xab, 0x9a, 0xba, 0xe6, 0xcf, 0x11, 0xa7, 0x00, 0x44, 0xc2, 0x5e,
+ 0xd1, 0xba, 0x9b, 0xaa, 0xfe, 0x03, 0xdd, 0xdc, 0xef, 0x41, 0x89, 0x9c, 0xac, 0x64, 0x13,
+ 0xd9, 0x6a, 0x8a, 0x55, 0xa0, 0x5b, 0xff, 0x12, 0x92, 0x37, 0x52, 0x6a, 0x91, 0xa4, 0x6e,
+ 0x9e, 0x61, 0xb7, 0xfe, 0xb0, 0x17, 0x8e, 0x67, 0x0f, 0x88, 0x46, 0xa7, 0x9e, 0xb1, 0xdb,
+ 0x68, 0x77, 0x70, 0xb5, 0x77, 0xf2, 0x7e, 0x33, 0xb1, 0x3e, 0x10, 0xc4, 0x63, 0x36, 0xd0,
+ 0x13, 0x27, 0xd3, 0x29, 0xc3, 0xb6, 0x5d, 0xf6, 0x5d, 0xa7, 0xd8, 0x25, 0x5c, 0x0b, 0x65,
+ 0x99, 0xfa, 0xf9, 0x5f, 0x1d, 0xee, 0xd1, 0x86, 0x64, 0x7c, 0x44, 0xcb, 0xa0, 0x12, 0x52,
+ 0x4c, 0xd4, 0x46, 0x81, 0xae, 0x07, 0xdb, 0xc7, 0x13, 0x29, 0xce, 0x9b, 0xcf, 0x1c, 0x06,
+ 0xd2, 0x0f, 0x2d, 0xbb, 0x12, 0x33, 0xb9, 0xb1, 0x0f, 0x67, 0x5d, 0x3f, 0x0c, 0xe4, 0xfa,
+ 0x67, 0x26, 0xe2, 0x89, 0xa2, 0xd5, 0x66, 0x29, 0x1c, 0xe2, 0x8e, 0xbb, 0x7b, 0xcb, 0xcc,
+ 0x70, 0x7e, 0x4f, 0x0e, 0xd3, 0x5d, 0x64, 0x64, 0x1b, 0x27, 0xbb, 0xda, 0xa9, 0x08, 0x2b,
+ 0x62, 0xd4, 0xca, 0xc3, 0x3a, 0x23, 0x39, 0x58, 0x57, 0xaf, 0x7b, 0x8b, 0x0c, 0x5b, 0x2e,
+ 0xfc, 0x42, 0x57, 0x59, 0x39, 0x2e, 0x6d, 0x39, 0x97, 0xdb, 0x5b, 0x5c, 0xb9, 0x59, 0x71,
+ 0x42, 0xf3, 0xcd, 0xea, 0xda, 0x86, 0x54, 0x86, 0x61, 0x8d, 0x93, 0x66, 0xc7, 0x65, 0xd1,
+ 0x98, 0xcb
+ };
+
+ DO(dh_set_pg_dhparam(dhparam_der, sizeof(dhparam_der), &k));
+ DO(dh_generate_key(&yarrow_prng, find_prng ("yarrow"), &k));
+ if (mp_unsigned_bin_size(k.prime) > sizeof(buf)) {
+ printf("dhparam_test: short buf\n");
+ dh_free(&k);
+ return CRYPT_ERROR;
+ }
+ DO(mp_to_unsigned_bin(k.prime, buf));
+ if (compare_testvector(buf, sizeof(prime), prime, sizeof(prime), "dhparam_test", 1)) {
+ printf("dhparam_test: prime mismatch\n");
+ dh_free(&k);
+ return CRYPT_ERROR;
+ }
+ if (mp_cmp_d(k.base, 2) != LTC_MP_EQ) {
+ printf("dhparam_test: base mismatch\n");
+ dh_free(&k);
+ return CRYPT_ERROR;
+ }
+ dh_free(&k);
+ return CRYPT_OK;
+}
+
+static int _set_test(void)
+{
+ dh_key k1, k2, k3;
+ unsigned char buf[4096];
+ unsigned long len;
+ int i;
+ unsigned char gbin[] = { 0x02 };
+ unsigned char pbin[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+ unsigned char xbin[] = {
+ 0xA6, 0x68, 0x1A, 0xDC, 0x38, 0x6C, 0xE9, 0x44, 0xC3, 0xDE, 0xD9, 0xA7, 0x30, 0x1D, 0xCC, 0x9C,
+ 0x51, 0x82, 0x50, 0xE3, 0xED, 0xB6, 0x2F, 0x95, 0x91, 0x98, 0xF8, 0xDC, 0x00, 0x57, 0xDD, 0x6F,
+ 0xB5, 0x7A, 0xBA, 0xFD, 0x78, 0x81, 0x98, 0xB1
+ };
+ unsigned char ybin[] = {
+ 0x39, 0x04, 0x66, 0x32, 0xC8, 0x34, 0x41, 0x8D, 0xFA, 0x07, 0xB3, 0x09, 0x15, 0x38, 0xB6, 0x14,
+ 0xD1, 0xFB, 0x5D, 0xBB, 0x78, 0x5C, 0x0F, 0xBE, 0xA3, 0xB9, 0x8B, 0x29, 0x5B, 0xC0, 0xCD, 0x07,
+ 0x6A, 0x88, 0xD9, 0x45, 0x21, 0x41, 0xA2, 0x69, 0xE8, 0xBA, 0xEB, 0x1D, 0xD6, 0x54, 0xEB, 0xA0,
+ 0x3A, 0x57, 0x05, 0x31, 0x8D, 0x12, 0x97, 0x54, 0xCD, 0xF4, 0x00, 0x3A, 0x8C, 0x39, 0x92, 0x40,
+ 0xFB, 0xB8, 0xF1, 0x62, 0x49, 0x0F, 0x6F, 0x0D, 0xC7, 0x0E, 0x41, 0x4B, 0x6F, 0xEE, 0x88, 0x08,
+ 0x6A, 0xFA, 0xA4, 0x8E, 0x9F, 0x3A, 0x24, 0x8E, 0xDC, 0x09, 0x34, 0x52, 0x66, 0x3D, 0x34, 0xE0,
+ 0xE8, 0x09, 0xD4, 0xF6, 0xBA, 0xDB, 0xB3, 0x6F, 0x80, 0xB6, 0x81, 0x3E, 0xBF, 0x7C, 0x32, 0x81,
+ 0xB8, 0x62, 0x20, 0x9E, 0x56, 0x04, 0xBD, 0xEA, 0x8B, 0x8F, 0x5F, 0x7B, 0xFD, 0xC3, 0xEE, 0xB7,
+ 0xAD, 0xB7, 0x30, 0x48, 0x28, 0x9B, 0xCE, 0xA0, 0xF5, 0xA5, 0xCD, 0xEE, 0x7D, 0xF9, 0x1C, 0xD1,
+ 0xF0, 0xBA, 0x63, 0x2F, 0x06, 0xDB, 0xE9, 0xBA, 0x7E, 0xF0, 0x14, 0xB8, 0x4B, 0x02, 0xD4, 0x97,
+ 0xCA, 0x7D, 0x0C, 0x60, 0xF7, 0x34, 0x75, 0x2A, 0x64, 0x9D, 0xA4, 0x96, 0x94, 0x6B, 0x4E, 0x53,
+ 0x1B, 0x30, 0xD9, 0xF8, 0x2E, 0xDD, 0x85, 0x56, 0x36, 0xC0, 0xB0, 0xF2, 0xAE, 0x23, 0x2E, 0x41,
+ 0x86, 0x45, 0x4E, 0x88, 0x87, 0xBB, 0x42, 0x3E, 0x32, 0xA5, 0xA2, 0x49, 0x5E, 0xAC, 0xBA, 0x99,
+ 0x62, 0x0A, 0xCD, 0x03, 0xA3, 0x83, 0x45, 0xEB, 0xB6, 0x73, 0x5E, 0x62, 0x33, 0x0A, 0x8E, 0xE9,
+ 0xAA, 0x6C, 0x83, 0x70, 0x41, 0x0F, 0x5C, 0xD4, 0x5A, 0xF3, 0x7E, 0xE9, 0x0A, 0x0D, 0xA9, 0x5B,
+ 0xE9, 0x6F, 0xC9, 0x39, 0xE8, 0x8F, 0xE0, 0xBD, 0x2C, 0xD0, 0x9F, 0xC8, 0xF5, 0x24, 0x20, 0x8C
+ };
+
+ struct {
+ int radix;
+ void* g; int glen;
+ void* p; int plen;
+ void* x; int xlen;
+ void* y; int ylen;
+ } test[1] = {
+ { 256, gbin, sizeof(gbin), pbin, sizeof(pbin), xbin, sizeof(xbin), ybin, sizeof(ybin) }
+ };
+
+ unsigned char export_private[] = {
+ 0x30, 0x82, 0x01, 0x3A, 0x02, 0x01, 0x00, 0x03, 0x02, 0x07, 0x80, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x02, 0x01, 0x02, 0x02, 0x29, 0x00, 0xA6, 0x68, 0x1A, 0xDC, 0x38, 0x6C, 0xE9, 0x44, 0xC3, 0xDE,
+ 0xD9, 0xA7, 0x30, 0x1D, 0xCC, 0x9C, 0x51, 0x82, 0x50, 0xE3, 0xED, 0xB6, 0x2F, 0x95, 0x91, 0x98,
+ 0xF8, 0xDC, 0x00, 0x57, 0xDD, 0x6F, 0xB5, 0x7A, 0xBA, 0xFD, 0x78, 0x81, 0x98, 0xB1
+ };
+ unsigned char export_public[] = {
+ 0x30, 0x82, 0x02, 0x13, 0x02, 0x01, 0x00, 0x03, 0x02, 0x07, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x02, 0x01, 0x02, 0x02, 0x82, 0x01, 0x00, 0x39, 0x04, 0x66, 0x32, 0xC8, 0x34, 0x41, 0x8D, 0xFA,
+ 0x07, 0xB3, 0x09, 0x15, 0x38, 0xB6, 0x14, 0xD1, 0xFB, 0x5D, 0xBB, 0x78, 0x5C, 0x0F, 0xBE, 0xA3,
+ 0xB9, 0x8B, 0x29, 0x5B, 0xC0, 0xCD, 0x07, 0x6A, 0x88, 0xD9, 0x45, 0x21, 0x41, 0xA2, 0x69, 0xE8,
+ 0xBA, 0xEB, 0x1D, 0xD6, 0x54, 0xEB, 0xA0, 0x3A, 0x57, 0x05, 0x31, 0x8D, 0x12, 0x97, 0x54, 0xCD,
+ 0xF4, 0x00, 0x3A, 0x8C, 0x39, 0x92, 0x40, 0xFB, 0xB8, 0xF1, 0x62, 0x49, 0x0F, 0x6F, 0x0D, 0xC7,
+ 0x0E, 0x41, 0x4B, 0x6F, 0xEE, 0x88, 0x08, 0x6A, 0xFA, 0xA4, 0x8E, 0x9F, 0x3A, 0x24, 0x8E, 0xDC,
+ 0x09, 0x34, 0x52, 0x66, 0x3D, 0x34, 0xE0, 0xE8, 0x09, 0xD4, 0xF6, 0xBA, 0xDB, 0xB3, 0x6F, 0x80,
+ 0xB6, 0x81, 0x3E, 0xBF, 0x7C, 0x32, 0x81, 0xB8, 0x62, 0x20, 0x9E, 0x56, 0x04, 0xBD, 0xEA, 0x8B,
+ 0x8F, 0x5F, 0x7B, 0xFD, 0xC3, 0xEE, 0xB7, 0xAD, 0xB7, 0x30, 0x48, 0x28, 0x9B, 0xCE, 0xA0, 0xF5,
+ 0xA5, 0xCD, 0xEE, 0x7D, 0xF9, 0x1C, 0xD1, 0xF0, 0xBA, 0x63, 0x2F, 0x06, 0xDB, 0xE9, 0xBA, 0x7E,
+ 0xF0, 0x14, 0xB8, 0x4B, 0x02, 0xD4, 0x97, 0xCA, 0x7D, 0x0C, 0x60, 0xF7, 0x34, 0x75, 0x2A, 0x64,
+ 0x9D, 0xA4, 0x96, 0x94, 0x6B, 0x4E, 0x53, 0x1B, 0x30, 0xD9, 0xF8, 0x2E, 0xDD, 0x85, 0x56, 0x36,
+ 0xC0, 0xB0, 0xF2, 0xAE, 0x23, 0x2E, 0x41, 0x86, 0x45, 0x4E, 0x88, 0x87, 0xBB, 0x42, 0x3E, 0x32,
+ 0xA5, 0xA2, 0x49, 0x5E, 0xAC, 0xBA, 0x99, 0x62, 0x0A, 0xCD, 0x03, 0xA3, 0x83, 0x45, 0xEB, 0xB6,
+ 0x73, 0x5E, 0x62, 0x33, 0x0A, 0x8E, 0xE9, 0xAA, 0x6C, 0x83, 0x70, 0x41, 0x0F, 0x5C, 0xD4, 0x5A,
+ 0xF3, 0x7E, 0xE9, 0x0A, 0x0D, 0xA9, 0x5B, 0xE9, 0x6F, 0xC9, 0x39, 0xE8, 0x8F, 0xE0, 0xBD, 0x2C,
+ 0xD0, 0x9F, 0xC8, 0xF5, 0x24, 0x20, 0x8C
+ };
+
+ for (i = 0; i < 1; i++) {
+ DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k1));
+ DO(dh_set_key(test[i].x, test[i].xlen, PK_PRIVATE, &k1));
+
+ len = sizeof(buf);
+ DO(dh_export(buf, &len, PK_PRIVATE, &k1));
+ if (compare_testvector(buf, len, export_private, sizeof(export_private), "radix_test", i*10 + 0)) {
+ printf("radix_test: dh_export+PK_PRIVATE mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ len = sizeof(buf);
+ DO(dh_export(buf, &len, PK_PUBLIC, &k1));
+ if (compare_testvector(buf, len, export_public, sizeof(export_public), "radix_test", i*10 + 1)) {
+ printf("radix_test: dh_export+PK_PUBLIC mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ len = sizeof(buf);
+ DO(dh_export_key(buf, &len, PK_PRIVATE, &k1));
+ if (compare_testvector(buf, len, xbin, sizeof(xbin), "radix_test", i*10 + 2)) {
+ printf("radix_test: dh_export+PK_PRIVATE mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ len = sizeof(buf);
+ DO(dh_export_key(buf, &len, PK_PUBLIC, &k1));
+ if (compare_testvector(buf, len, ybin, sizeof(ybin), "radix_test", i*10 + 3)) {
+ printf("radix_test: dh_export+PK_PUBLIC mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ dh_free(&k1);
+
+ DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k1));
+ DO(dh_set_key(test[i].x, test[i].xlen, PK_PRIVATE, &k1));
+
+ len = sizeof(buf);
+ DO(dh_export(buf, &len, PK_PRIVATE, &k1));
+ if (compare_testvector(buf, len, export_private, sizeof(export_private), "radix_test", i*10 + 4)) {
+ printf("radix_test: dh_export+PK_PRIVATE mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ len = sizeof(buf);
+ DO(dh_export(buf, &len, PK_PUBLIC, &k1));
+ if (compare_testvector(buf, len, export_public, sizeof(export_public), "radix_test", i*10 + 5)) {
+ printf("radix_test: dh_export+PK_PUBLIC mismatch\n");
+ dh_free(&k1);
+ return CRYPT_ERROR;
+ }
+ dh_free(&k1);
+
+ DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k2));
+ DO(dh_set_key(test[i].y, test[i].ylen, PK_PUBLIC, &k2));
+
+ len = sizeof(buf);
+ DO(dh_export(buf, &len, PK_PUBLIC, &k2));
+ if (compare_testvector(buf, len, export_public, sizeof(export_public), "radix_test", i*10 + 6)) {
+ printf("radix_test: dh_export+PK_PUBLIC mismatch\n");
+ dh_free(&k2);
+ return CRYPT_ERROR;
+ }
+ len = sizeof(buf);
+ DO(dh_export_key(buf, &len, PK_PUBLIC, &k2));
+ if (compare_testvector(buf, len, ybin, sizeof(ybin), "radix_test", i*10 + 7)) {
+ printf("radix_test: dh_export+PK_PUBLIC mismatch\n");
+ dh_free(&k2);
+ return CRYPT_ERROR;
+ }
+ dh_free(&k2);
+
+ DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k3));
+ DO(dh_generate_key(&yarrow_prng, find_prng("yarrow"), &k3));
+
+ len = mp_unsigned_bin_size(k3.prime);
+ DO(mp_to_unsigned_bin(k3.prime, buf));
+ if (compare_testvector(buf, len, pbin, sizeof(pbin), "radix_test", i*10 + 8)) {
+ printf("radix_test: dh_make_key_ex prime mismatch\n");
+ dh_free(&k3);
+ return CRYPT_ERROR;
+ }
+ len = mp_unsigned_bin_size(k3.base);
+ DO(mp_to_unsigned_bin(k3.base, buf));
+ if (compare_testvector(buf, len, gbin, sizeof(gbin), "radix_test", i*10 + 9)) {
+ printf("radix_test: dh_make_key_ex base mismatch\n");
+ dh_free(&k3);
+ return CRYPT_ERROR;
+ }
+ dh_free(&k3);
+ }
+
+ return CRYPT_OK;
+}
+
+static int _basic_test(void)
+{
+ unsigned char buf[3][4096];
+ unsigned long x, y, z;
+ int size;
+ dh_key usera, userb;
+
+ /* make up two keys */
+ DO(dh_set_pg_groupsize(KEYSIZE/8, &usera));
+ DO(dh_generate_key(&yarrow_prng, find_prng ("yarrow"), &usera));
+ DO(dh_set_pg_groupsize(KEYSIZE/8, &userb));
+ DO(dh_generate_key(&yarrow_prng, find_prng ("yarrow"), &userb));
+
+ /* make the shared secret */
+ x = KEYSIZE;
+ DO(dh_shared_secret (&usera, &userb, buf[0], &x));
+
+ y = KEYSIZE;
+ DO(dh_shared_secret (&userb, &usera, buf[1], &y));
+ if (y != x) {
+ fprintf(stderr, "DH Shared keys are not same size.\n");
+ dh_free (&usera);
+ dh_free (&userb);
+ return CRYPT_ERROR;
+ }
+ if (memcmp (buf[0], buf[1], x)) {
+ fprintf(stderr, "DH Shared keys not same contents.\n");
+ dh_free (&usera);
+ dh_free (&userb);
+ return CRYPT_ERROR;
+ }
+
+ /* now export userb */
+ y = KEYSIZE;
+ DO(dh_export (buf[1], &y, PK_PUBLIC, &userb));
+ dh_free (&userb);
+
+ /* import and make the shared secret again */
+ DO(dh_import (buf[1], y, &userb));
+ z = KEYSIZE;
+ DO(dh_shared_secret (&usera, &userb, buf[2], &z));
+
+ dh_free (&usera);
+ dh_free (&userb);
+
+ if (z != x) {
+ fprintf(stderr, "failed. Size don't match?\n");
+ return CRYPT_ERROR;
+ }
+ if (memcmp (buf[0], buf[2], x)) {
+ fprintf(stderr, "Failed. Content didn't match.\n");
+ return CRYPT_ERROR;
+ }
+
+ for (x = 0; ltc_dh_sets[x].size != 0; x++) {
+ DO(dh_set_pg_groupsize(ltc_dh_sets[x].size, &usera));
+ DO(dh_generate_key(&yarrow_prng, find_prng ("yarrow"), &usera));
+ size = dh_get_groupsize(&usera);
+ dh_free(&usera);
+ if (size != ltc_dh_sets[x].size) {
+ fprintf(stderr, "dh_groupsize mismatch %d %d\n", size, ltc_dh_sets[x].size);
+ return CRYPT_ERROR;
+ }
+ dh_free(&usera);
+ }
+
+ return CRYPT_OK;
+}
+
+int dh_test(void)
+{
+ int fails = 0;
+ if (_prime_test() != CRYPT_OK) fails++;
+ if (_basic_test() != CRYPT_OK) fails++;
+ if (_dhparam_test() != CRYPT_OK) fails++;
+ if (_set_test() != CRYPT_OK) fails++;
+ return fails > 0 ? CRYPT_FAIL_TESTVECTOR : CRYPT_OK;
+}
+
+#else
+
+int dh_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/dsa_test.c b/libtomcrypt/tests/dsa_test.c
new file mode 100644
index 0000000..a429993
--- /dev/null
+++ b/libtomcrypt/tests/dsa_test.c
@@ -0,0 +1,400 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MDSA) && defined(LTC_TEST_MPI)
+
+/* This is the private key from test_dsa.key */
+static const unsigned char openssl_priv_dsa[] = {
+ 0x30, 0x82, 0x01, 0xbb, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc5,
+ 0x0a, 0x37, 0x51, 0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70, 0xbd, 0x4a,
+ 0x6f, 0x6b, 0x4a, 0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99, 0x38, 0x7d,
+ 0x9a, 0x64, 0xd6, 0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac, 0xa8, 0xac,
+ 0xc6, 0x1b, 0x65, 0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a, 0x18, 0x2c,
+ 0xee, 0xa1, 0x07, 0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90, 0xc7, 0x03,
+ 0x21, 0xfa, 0x09, 0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb, 0xfd, 0xbf,
+ 0xb3, 0xef, 0xad, 0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06, 0x92, 0x4a,
+ 0x85, 0x2a, 0xff, 0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6, 0x67, 0x41,
+ 0x84, 0x5a, 0xc0, 0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62, 0x05, 0xa4,
+ 0xfa, 0x48, 0xa0, 0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe, 0xb9, 0x81,
+ 0xab, 0xee, 0xbe, 0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00, 0xaa, 0x5b,
+ 0xd7, 0xf4, 0xe5, 0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca, 0x00, 0xc7,
+ 0xa6, 0x35, 0x71, 0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b, 0x92, 0xe4,
+ 0xff, 0x59, 0x29, 0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2, 0xad, 0x14,
+ 0x40, 0x55, 0x6f, 0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44, 0xb3, 0xd4,
+ 0xfc, 0x45, 0x15, 0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba, 0x37, 0x10,
+ 0xa5, 0x89, 0x47, 0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8, 0xb4, 0x7a,
+ 0x35, 0xcb, 0x9d, 0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96, 0x94, 0xc4,
+ 0xa6, 0x0c, 0x7d, 0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a, 0x0e, 0xc2,
+ 0x13, 0xfb, 0xeb, 0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff, 0x72, 0x30,
+ 0x05, 0xde, 0x8a, 0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55, 0xd6, 0x2d,
+ 0x1d, 0x1e, 0xdb, 0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17, 0x97, 0x98,
+ 0x0b, 0x8d, 0x87, 0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab, 0x67, 0x6e,
+ 0x87, 0x68, 0x72, 0x23, 0xdc, 0x02, 0x81, 0x80, 0x53, 0x16, 0xb0, 0xfb,
+ 0xbf, 0x59, 0x8a, 0x5e, 0x55, 0x95, 0xc1, 0x4f, 0xac, 0x43, 0xb8, 0x08,
+ 0x53, 0xe6, 0xcf, 0x0d, 0x92, 0x23, 0xfa, 0xb1, 0x84, 0x59, 0x52, 0x39,
+ 0xbf, 0xcb, 0xf2, 0x2d, 0x38, 0x3a, 0xdd, 0x93, 0x52, 0x05, 0x49, 0x7e,
+ 0x2b, 0x12, 0xc4, 0x61, 0x73, 0xe3, 0x6f, 0x54, 0xbd, 0x96, 0xe5, 0xa7,
+ 0xaa, 0xa9, 0x5a, 0x58, 0xa4, 0xb7, 0x67, 0xd2, 0xc0, 0xbd, 0xc8, 0x1e,
+ 0xb1, 0x3a, 0x12, 0x4f, 0x98, 0xc0, 0x05, 0xef, 0x39, 0x5d, 0x6a, 0xba,
+ 0xb7, 0x0b, 0x3b, 0xd8, 0xb7, 0x95, 0xdd, 0x79, 0x6e, 0xa2, 0xd2, 0x84,
+ 0x73, 0x47, 0x03, 0x88, 0xb4, 0x64, 0xd9, 0xb9, 0xb8, 0x4f, 0xf1, 0xc9,
+ 0x34, 0xbb, 0xf9, 0x73, 0x66, 0xf5, 0x7c, 0x2e, 0x11, 0xfe, 0xc3, 0x31,
+ 0xe6, 0x08, 0x38, 0x59, 0x67, 0x81, 0xeb, 0x6d, 0x41, 0x27, 0xd7, 0x0d,
+ 0x74, 0xaf, 0xa0, 0x35, 0x02, 0x15, 0x00, 0x99, 0x36, 0xe5, 0xe4, 0xe9,
+ 0xfb, 0x28, 0xbe, 0x91, 0xf5, 0x06, 0x5f, 0xe8, 0xc9, 0x35, 0xb3, 0xf5,
+ 0xd8, 0x1f, 0xc5
+};
+
+/* private key - raw hexadecimal numbers */
+static const char *hex_g = "3B92E4FF5929150B08995A7BF2AD1440556FA047FF9099B344B3D4FC451505AE6722439CBA3710A5894737ECCCF5AEADA8B47A35CB9D935CEDE6B07E9694C4A60C7DD6708A094F814A0EC213FBEB16BFEAA4F456FF723005DE8A443FBEC6852655D62D1D1EDB15DAA445833C1797980B8D87F3490D90BDA9AB676E87687223DC";
+static const char *hex_p = "C50A37515CABD618D5A270BD4A6F6B4AF9E139950F2B99387D9A64D64CB5967ADCEDACA8ACC61B655ADEDB0061251A182CEEA10790625E4D123190C70321FA09E7B173D78EAFDBFDBFB3EFADD1A12A036DE706924A852AFF7A0166531FEAC66741845AC06CED62F9C2626205A4FA48A066EC35C9A811FEB981ABEEBE31B6BFCF";
+static const char *hex_q = "AA5BD7F4E5062413E58835CA00C7A635716194C5";
+static const char *hex_x = "9936E5E4E9FB28BE91F5065FE8C935B3F5D81FC5";
+static const char *hex_y = "5316B0FBBF598A5E5595C14FAC43B80853E6CF0D9223FAB184595239BFCBF22D383ADD935205497E2B12C46173E36F54BD96E5A7AAA95A58A4B767D2C0BDC81EB13A124F98C005EF395D6ABAB70B3BD8B795DD796EA2D28473470388B464D9B9B84FF1C934BBF97366F57C2E11FEC331E60838596781EB6D4127D70D74AFA035";
+
+/* The public part of test_dsa.key in SubjectPublicKeyInfo format */
+static const unsigned char openssl_pub_dsa[] = {
+ 0x30, 0x82, 0x01, 0xb6, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x07, 0x2a, 0x86,
+ 0x48, 0xce, 0x38, 0x04, 0x01, 0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81,
+ 0x00, 0xc5, 0x0a, 0x37, 0x51, 0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70,
+ 0xbd, 0x4a, 0x6f, 0x6b, 0x4a, 0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99,
+ 0x38, 0x7d, 0x9a, 0x64, 0xd6, 0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac,
+ 0xa8, 0xac, 0xc6, 0x1b, 0x65, 0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a,
+ 0x18, 0x2c, 0xee, 0xa1, 0x07, 0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90,
+ 0xc7, 0x03, 0x21, 0xfa, 0x09, 0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb,
+ 0xfd, 0xbf, 0xb3, 0xef, 0xad, 0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06,
+ 0x92, 0x4a, 0x85, 0x2a, 0xff, 0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6,
+ 0x67, 0x41, 0x84, 0x5a, 0xc0, 0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62,
+ 0x05, 0xa4, 0xfa, 0x48, 0xa0, 0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe,
+ 0xb9, 0x81, 0xab, 0xee, 0xbe, 0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00,
+ 0xaa, 0x5b, 0xd7, 0xf4, 0xe5, 0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca,
+ 0x00, 0xc7, 0xa6, 0x35, 0x71, 0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b,
+ 0x92, 0xe4, 0xff, 0x59, 0x29, 0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2,
+ 0xad, 0x14, 0x40, 0x55, 0x6f, 0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44,
+ 0xb3, 0xd4, 0xfc, 0x45, 0x15, 0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba,
+ 0x37, 0x10, 0xa5, 0x89, 0x47, 0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8,
+ 0xb4, 0x7a, 0x35, 0xcb, 0x9d, 0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96,
+ 0x94, 0xc4, 0xa6, 0x0c, 0x7d, 0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a,
+ 0x0e, 0xc2, 0x13, 0xfb, 0xeb, 0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff,
+ 0x72, 0x30, 0x05, 0xde, 0x8a, 0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55,
+ 0xd6, 0x2d, 0x1d, 0x1e, 0xdb, 0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17,
+ 0x97, 0x98, 0x0b, 0x8d, 0x87, 0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab,
+ 0x67, 0x6e, 0x87, 0x68, 0x72, 0x23, 0xdc, 0x03, 0x81, 0x84, 0x00, 0x02,
+ 0x81, 0x80, 0x53, 0x16, 0xb0, 0xfb, 0xbf, 0x59, 0x8a, 0x5e, 0x55, 0x95,
+ 0xc1, 0x4f, 0xac, 0x43, 0xb8, 0x08, 0x53, 0xe6, 0xcf, 0x0d, 0x92, 0x23,
+ 0xfa, 0xb1, 0x84, 0x59, 0x52, 0x39, 0xbf, 0xcb, 0xf2, 0x2d, 0x38, 0x3a,
+ 0xdd, 0x93, 0x52, 0x05, 0x49, 0x7e, 0x2b, 0x12, 0xc4, 0x61, 0x73, 0xe3,
+ 0x6f, 0x54, 0xbd, 0x96, 0xe5, 0xa7, 0xaa, 0xa9, 0x5a, 0x58, 0xa4, 0xb7,
+ 0x67, 0xd2, 0xc0, 0xbd, 0xc8, 0x1e, 0xb1, 0x3a, 0x12, 0x4f, 0x98, 0xc0,
+ 0x05, 0xef, 0x39, 0x5d, 0x6a, 0xba, 0xb7, 0x0b, 0x3b, 0xd8, 0xb7, 0x95,
+ 0xdd, 0x79, 0x6e, 0xa2, 0xd2, 0x84, 0x73, 0x47, 0x03, 0x88, 0xb4, 0x64,
+ 0xd9, 0xb9, 0xb8, 0x4f, 0xf1, 0xc9, 0x34, 0xbb, 0xf9, 0x73, 0x66, 0xf5,
+ 0x7c, 0x2e, 0x11, 0xfe, 0xc3, 0x31, 0xe6, 0x08, 0x38, 0x59, 0x67, 0x81,
+ 0xeb, 0x6d, 0x41, 0x27, 0xd7, 0x0d, 0x74, 0xaf, 0xa0, 0x35
+};
+
+static unsigned char dsaparam_der[] = {
+ 0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81, 0x00, 0xc5, 0x0a, 0x37, 0x51,
+ 0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70, 0xbd, 0x4a, 0x6f, 0x6b, 0x4a,
+ 0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99, 0x38, 0x7d, 0x9a, 0x64, 0xd6,
+ 0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac, 0xa8, 0xac, 0xc6, 0x1b, 0x65,
+ 0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a, 0x18, 0x2c, 0xee, 0xa1, 0x07,
+ 0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90, 0xc7, 0x03, 0x21, 0xfa, 0x09,
+ 0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb, 0xfd, 0xbf, 0xb3, 0xef, 0xad,
+ 0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06, 0x92, 0x4a, 0x85, 0x2a, 0xff,
+ 0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6, 0x67, 0x41, 0x84, 0x5a, 0xc0,
+ 0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62, 0x05, 0xa4, 0xfa, 0x48, 0xa0,
+ 0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe, 0xb9, 0x81, 0xab, 0xee, 0xbe,
+ 0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00, 0xaa, 0x5b, 0xd7, 0xf4, 0xe5,
+ 0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca, 0x00, 0xc7, 0xa6, 0x35, 0x71,
+ 0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b, 0x92, 0xe4, 0xff, 0x59, 0x29,
+ 0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2, 0xad, 0x14, 0x40, 0x55, 0x6f,
+ 0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44, 0xb3, 0xd4, 0xfc, 0x45, 0x15,
+ 0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba, 0x37, 0x10, 0xa5, 0x89, 0x47,
+ 0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8, 0xb4, 0x7a, 0x35, 0xcb, 0x9d,
+ 0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96, 0x94, 0xc4, 0xa6, 0x0c, 0x7d,
+ 0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a, 0x0e, 0xc2, 0x13, 0xfb, 0xeb,
+ 0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff, 0x72, 0x30, 0x05, 0xde, 0x8a,
+ 0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55, 0xd6, 0x2d, 0x1d, 0x1e, 0xdb,
+ 0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17, 0x97, 0x98, 0x0b, 0x8d, 0x87,
+ 0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab, 0x67, 0x6e, 0x87, 0x68, 0x72,
+ 0x23, 0xdc
+ };
+
+
+static int _dsa_compat_test(void)
+{
+ dsa_key key;
+ unsigned char tmp[1024], buf[1024];
+ unsigned long x, len;
+ unsigned char key_parts[5][256];
+ unsigned long key_lens[5];
+ int stat;
+
+ DO(dsa_import(openssl_priv_dsa, sizeof(openssl_priv_dsa), &key));
+
+ x = sizeof(tmp);
+ DO(dsa_export(tmp, &x, PK_PRIVATE | PK_STD, &key));
+ if (compare_testvector(tmp, x, openssl_priv_dsa, sizeof(openssl_priv_dsa),
+ "DSA private export failed from dsa_import(priv_key)\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ x = sizeof(tmp);
+ DO(dsa_export(tmp, &x, PK_PUBLIC | PK_STD, &key));
+ if (compare_testvector(tmp, x, openssl_pub_dsa, sizeof(openssl_pub_dsa),
+ "DSA public export failed from dsa_import(priv_key)\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ DO(dsa_import(openssl_pub_dsa, sizeof(openssl_pub_dsa), &key));
+
+ x = sizeof(tmp);
+ DO(dsa_export(tmp, &x, PK_PUBLIC | PK_STD, &key));
+ if (compare_testvector(tmp, x, openssl_pub_dsa, sizeof(openssl_pub_dsa),
+ "DSA public export failed from dsa_import(pub_key)\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ /* try import private key from raw hexadecimal numbers */
+ for (x = 0; x < 5; ++x) {
+ key_lens[x] = sizeof(key_parts[x]);
+ }
+ DO(radix_to_bin(hex_p, 16, key_parts[0], &key_lens[0]));
+ DO(radix_to_bin(hex_q, 16, key_parts[1], &key_lens[1]));
+ DO(radix_to_bin(hex_g, 16, key_parts[2], &key_lens[2]));
+ DO(radix_to_bin(hex_y, 16, key_parts[3], &key_lens[3]));
+ DO(radix_to_bin(hex_x, 16, key_parts[4], &key_lens[4]));
+
+ DO(dsa_set_pqg(key_parts[0], key_lens[0],
+ key_parts[1], key_lens[1],
+ key_parts[2], key_lens[2],
+ &key));
+ DO(dsa_set_key(key_parts[4], key_lens[4],
+ PK_PRIVATE,
+ &key));
+ len = sizeof(buf);
+ DO(dsa_export(buf, &len, PK_PRIVATE | PK_STD, &key));
+ if (compare_testvector(buf, len, openssl_priv_dsa, sizeof(openssl_priv_dsa),
+ "DSA private export failed from dsa_set_pqg() & dsa_set_key()\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ /* try import public key from raw hexadecimal numbers */
+ DO(dsa_set_pqg(key_parts[0], key_lens[0],
+ key_parts[1], key_lens[1],
+ key_parts[2], key_lens[2],
+ &key));
+ DO(dsa_set_key(key_parts[3], key_lens[3],
+ PK_PUBLIC,
+ &key));
+ len = sizeof(buf);
+ DO(dsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
+ if (compare_testvector(buf, len, openssl_pub_dsa, sizeof(openssl_pub_dsa),
+ "DSA public export failed from dsa_set_pqg() & dsa_set_key()\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ /* try import dsaparam */
+ DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
+ DO(dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key));
+ /* verify it */
+ DO(dsa_verify_key(&key, &stat));
+ if (stat == 0) {
+ fprintf(stderr, "dsa_verify_key after dsa_set_pqg_dsaparam()");
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ /* try import dsaparam - our public key */
+ DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
+ DO(dsa_set_key(key_parts[3], key_lens[3],
+ PK_PUBLIC,
+ &key));
+ len = sizeof(buf);
+ DO(dsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
+ if (compare_testvector(buf, len, openssl_pub_dsa, sizeof(openssl_pub_dsa),
+ "DSA public export failed from dsa_set_pqg_dsaparam()\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ /* try import dsaparam - our private key */
+ DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
+ DO(dsa_set_key(key_parts[4], key_lens[4],
+ PK_PRIVATE,
+ &key));
+ len = sizeof(buf);
+ DO(dsa_export(buf, &len, PK_PRIVATE | PK_STD, &key));
+ if (compare_testvector(buf, len, openssl_priv_dsa, sizeof(openssl_priv_dsa),
+ "DSA private export failed from dsa_set_pqg_dsaparam()\n", __LINE__)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ dsa_free(&key);
+
+ return CRYPT_OK;
+}
+
+static int _dsa_wycheproof_test(void)
+{
+ /* test case from https://github.com/google/wycheproof/blob/master/testvectors/dsa_test.json
+ *
+ * "comment" : "appending unused 0's",
+ * "message" : "48656c6c6f",
+ * "result" : "invalid",
+ * "sig" : "303d021c1e41b479ad576905b960fe14eadb91b0ccf34843dab916173bb8c9cd021d00ade65988d237d30f9ef41dd424a4e1c8f16967cf3365813fe87862360000",
+ * "tcId" : 55
+ */
+ unsigned char msg[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };
+ unsigned char sig[] = { 0x30, 0x3d, 0x02, 0x1c, 0x1e, 0x41, 0xb4, 0x79, 0xad, 0x57, 0x69, 0x05, 0xb9, 0x60, 0xfe,
+ 0x14, 0xea, 0xdb, 0x91, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, 0xb9, 0x16, 0x17, 0x3b, 0xb8,
+ 0xc9, 0xcd, 0x02, 0x1d, 0x00, 0xad, 0xe6, 0x59, 0x88, 0xd2, 0x37, 0xd3, 0x0f, 0x9e, 0xf4,
+ 0x1d, 0xd4, 0x24, 0xa4, 0xe1, 0xc8, 0xf1, 0x69, 0x67, 0xcf, 0x33, 0x65, 0x81, 0x3f, 0xe8,
+ 0x78, 0x62, 0x36, 0x00, 0x00 };
+ const char* b64key =
+ "MIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7FnjuvNxjo6sSWHz79"
+ "NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwOjxSzNggooi/6JxEKPWKpk0U0CaD+"
+ "aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYpH51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGM"
+ "n/qdgYHnM423krcw17njSVkvaAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOTh"
+ "jBopo33fXqFD3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A"
+ "uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQNNNo6NHjBVNTk"
+ "pcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJsyB2p5wypifyRz6Rh5uixOdE"
+ "vSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjGjQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH"
+ "9kxoJts+xy9LVZmDS7TtsC98kOmkltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh+"
+ "+1/et1SEMWsiMt7lU92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHv"
+ "F9veA4IBBQACggEAHnf4QrGuD82ZKdOUFh1B4UYU/3UHqaMfSh8U0i4qYnofTllmJIg/GlsWjpQl"
+ "FG8i1fbuKHV0FHFLuZS6ESnwFdbgSnF+35tTCl1cq5TxRjHotM95rrNYzHQYRVU4QeisRhYw6ASm"
+ "L0Nna6Z5SvZomcN3uGnqYSp7n+ZhGqlr5S64tiyXkRe7vMqKfsHh/6scffz8cEhwDTrjhYE26Jdw"
+ "HXwpIbXf7x0fiX9Q2WyhtcLtxYytoYkZ41ZC8IB+6/oAyZoy9NCVwxiPeO1UcRvgMlxLUyrszWVA"
+ "pWfDJyJUQOoVMZveBlEEeaGGF5niW1fezHPANtdaBwK9NzyiMTSZMQ==";
+ unsigned char derkey[838];
+ unsigned long derlen = sizeof(derkey);
+ unsigned char hash[32];
+ unsigned long hashlen = sizeof(hash);
+ dsa_key key;
+ int stat;
+
+ DO(base64_decode((unsigned char*)b64key, strlen(b64key), derkey, &derlen));
+ if (derlen != 838) {
+ fprintf(stderr, "base64_decode failed, derlen=%lu (expected 838)\n", derlen);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ DO(dsa_import(derkey, derlen, &key));
+ DO(hash_memory(find_hash("sha224"), msg, sizeof(msg), hash, &hashlen));
+ if (hashlen != 28) {
+ fprintf(stderr, "hash_memory failed, hashlen=%lu (expected 32)\n", hashlen);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ stat = 666; /* intentionally not one, not zero */
+ DO(dsa_verify_hash(sig, sizeof(sig)-2, hash, hashlen, &stat, &key));
+ /* without the last two 0x00 bytes it is a valid signature */
+ if (stat != 1) {
+ fprintf(stderr, "dsa_verify_hash rejected valid signature\n");
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ stat = 666; /* intentionally not one, not zero */
+ DO(dsa_verify_hash(sig, sizeof(sig), hash, hashlen, &stat, &key));
+ /* this should be invalid */
+ if (stat != 0) {
+ fprintf(stderr, "dsa_verify_hash did not reject invalid signature\n");
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ dsa_free(&key);
+ return CRYPT_OK;
+}
+
+int dsa_test(void)
+{
+ unsigned char msg[16], out[1024], out2[1024], ch;
+ unsigned long x, y;
+ int stat1, stat2;
+ dsa_key key, key2;
+
+ DO(_dsa_compat_test());
+ DO(_dsa_wycheproof_test());
+
+ /* make a random key */
+ DO(dsa_generate_pqg(&yarrow_prng, find_prng("yarrow"), 20, 128, &key));
+ DO(dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key));
+
+ /* verify it */
+ DO(dsa_verify_key(&key, &stat1));
+ if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; }
+
+ /* encrypt a message */
+ for (ch = 0; ch < 16; ch++) { msg[ch] = ch; }
+ x = sizeof(out);
+ DO(dsa_encrypt_key(msg, 16, out, &x, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key));
+
+ /* decrypt */
+ y = sizeof(out2);
+ DO(dsa_decrypt_key(out, x, out2, &y, &key));
+
+ if (y != 16 || memcmp(out2, msg, 16)) {
+ fprintf(stderr, "dsa_decrypt failed, y == %lu\n", y);
+ return 1;
+ }
+
+ /* sign the message */
+ x = sizeof(out);
+ DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &yarrow_prng, find_prng("yarrow"), &key));
+
+ /* verify it once */
+ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key));
+
+ /* Modify and verify again */
+ msg[0] ^= 1;
+ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
+ msg[0] ^= 1;
+ if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; }
+
+ /* test exporting it */
+ y = sizeof(out2);
+ DO(dsa_export(out2, &y, PK_PRIVATE, &key));
+ DO(dsa_import(out2, y, &key2));
+
+ /* verify a signature with it */
+ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+ if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; }
+ dsa_free(&key2);
+
+ /* export as public now */
+ y = sizeof(out2);
+ DO(dsa_export(out2, &y, PK_PUBLIC, &key));
+
+ DO(dsa_import(out2, y, &key2));
+ /* verify a signature with it */
+ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+ if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; }
+ dsa_free(&key2);
+ dsa_free(&key);
+
+ return 0;
+}
+
+#else
+
+int dsa_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/ecc_test.c b/libtomcrypt/tests/ecc_test.c
new file mode 100644
index 0000000..a68fc31
--- /dev/null
+++ b/libtomcrypt/tests/ecc_test.c
@@ -0,0 +1,268 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MECC) && defined(LTC_TEST_MPI)
+
+static unsigned int sizes[] = {
+#ifdef LTC_ECC112
+14,
+#endif
+#ifdef LTC_ECC128
+16,
+#endif
+#ifdef LTC_ECC160
+20,
+#endif
+#ifdef LTC_ECC192
+24,
+#endif
+#ifdef LTC_ECC224
+28,
+#endif
+#ifdef LTC_ECC256
+32,
+#endif
+#ifdef LTC_ECC384
+48,
+#endif
+#ifdef LTC_ECC521
+65
+#endif
+};
+
+#ifdef LTC_ECC_SHAMIR
+int ecc_test_shamir(void)
+{
+ void *modulus, *mp, *kA, *kB, *rA, *rB;
+ ecc_point *G, *A, *B, *C1, *C2;
+ int x, y, z;
+ unsigned char buf[ECC_BUF_SIZE];
+
+ DO(mp_init_multi(&kA, &kB, &rA, &rB, &modulus, NULL));
+ LTC_ARGCHK((G = ltc_ecc_new_point()) != NULL);
+ LTC_ARGCHK((A = ltc_ecc_new_point()) != NULL);
+ LTC_ARGCHK((B = ltc_ecc_new_point()) != NULL);
+ LTC_ARGCHK((C1 = ltc_ecc_new_point()) != NULL);
+ LTC_ARGCHK((C2 = ltc_ecc_new_point()) != NULL);
+
+ for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) {
+ /* get the base point */
+ for (z = 0; ltc_ecc_sets[z].name; z++) {
+ if (sizes[z] < (unsigned int)ltc_ecc_sets[z].size) break;
+ }
+ LTC_ARGCHK(ltc_ecc_sets[z].name != NULL);
+
+ /* load it */
+ DO(mp_read_radix(G->x, ltc_ecc_sets[z].Gx, 16));
+ DO(mp_read_radix(G->y, ltc_ecc_sets[z].Gy, 16));
+ DO(mp_set(G->z, 1));
+ DO(mp_read_radix(modulus, ltc_ecc_sets[z].prime, 16));
+ DO(mp_montgomery_setup(modulus, &mp));
+
+ /* do 100 random tests */
+ for (y = 0; y < 100; y++) {
+ /* pick a random r1, r2 */
+ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
+ DO(mp_read_unsigned_bin(rA, buf, sizes[x]));
+ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
+ DO(mp_read_unsigned_bin(rB, buf, sizes[x]));
+
+ /* compute rA * G = A */
+ DO(ltc_mp.ecc_ptmul(rA, G, A, modulus, 1));
+
+ /* compute rB * G = B */
+ DO(ltc_mp.ecc_ptmul(rB, G, B, modulus, 1));
+
+ /* pick a random kA, kB */
+ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
+ DO(mp_read_unsigned_bin(kA, buf, sizes[x]));
+ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
+ DO(mp_read_unsigned_bin(kB, buf, sizes[x]));
+
+ /* now, compute kA*A + kB*B = C1 using the older method */
+ DO(ltc_mp.ecc_ptmul(kA, A, C1, modulus, 0));
+ DO(ltc_mp.ecc_ptmul(kB, B, C2, modulus, 0));
+ DO(ltc_mp.ecc_ptadd(C1, C2, C1, modulus, mp));
+ DO(ltc_mp.ecc_map(C1, modulus, mp));
+
+ /* now compute using mul2add */
+ DO(ltc_mp.ecc_mul2add(A, kA, B, kB, C2, modulus));
+
+ /* is they the sames? */
+ if ((mp_cmp(C1->x, C2->x) != LTC_MP_EQ) || (mp_cmp(C1->y, C2->y) != LTC_MP_EQ) || (mp_cmp(C1->z, C2->z) != LTC_MP_EQ)) {
+ fprintf(stderr, "ECC failed shamir test: size=%d, testno=%d\n", sizes[x], y);
+ return 1;
+ }
+ }
+ mp_montgomery_free(mp);
+ }
+ ltc_ecc_del_point(C2);
+ ltc_ecc_del_point(C1);
+ ltc_ecc_del_point(B);
+ ltc_ecc_del_point(A);
+ ltc_ecc_del_point(G);
+ mp_clear_multi(kA, kB, rA, rB, modulus, NULL);
+ return 0;
+}
+#endif
+
+int ecc_tests (void)
+{
+ unsigned char buf[4][4096], ch;
+ unsigned long x, y, z, s;
+ int stat, stat2;
+ ecc_key usera, userb, pubKey, privKey;
+
+ DO(ecc_test ());
+
+ for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) {
+ /* make up two keys */
+ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
+ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb));
+
+ /* make the shared secret */
+ x = sizeof(buf[0]);
+ DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
+
+ y = sizeof(buf[1]);
+ DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
+
+ if (y != x) {
+ fprintf(stderr, "ecc Shared keys are not same size.");
+ return 1;
+ }
+
+ if (memcmp (buf[0], buf[1], x)) {
+ fprintf(stderr, "ecc Shared keys not same contents.");
+ return 1;
+ }
+
+ /* now export userb */
+ y = sizeof(buf[0]);
+ DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
+ ecc_free (&userb);
+
+ /* import and make the shared secret again */
+ DO(ecc_import (buf[1], y, &userb));
+
+ z = sizeof(buf[0]);
+ DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
+
+ if (z != x) {
+ fprintf(stderr, "failed. Size don't match?");
+ return 1;
+ }
+ if (memcmp (buf[0], buf[2], x)) {
+ fprintf(stderr, "Failed. Contents didn't match.");
+ return 1;
+ }
+
+ /* export with ANSI X9.63 */
+ y = sizeof(buf[1]);
+ DO(ecc_ansi_x963_export(&userb, buf[1], &y));
+ ecc_free (&userb);
+
+ /* now import the ANSI key */
+ DO(ecc_ansi_x963_import(buf[1], y, &userb));
+
+ /* shared secret */
+ z = sizeof(buf[0]);
+ DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
+
+ if (z != x) {
+ fprintf(stderr, "failed. Size don't match?");
+ return 1;
+ }
+ if (memcmp (buf[0], buf[2], x)) {
+ fprintf(stderr, "Failed. Contents didn't match.");
+ return 1;
+ }
+
+ ecc_free (&usera);
+ ecc_free (&userb);
+
+ /* test encrypt_key */
+ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
+
+ /* export key */
+ x = sizeof(buf[0]);
+ DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera));
+ DO(ecc_import(buf[0], x, &pubKey));
+ x = sizeof(buf[0]);
+ DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera));
+ DO(ecc_import(buf[0], x, &privKey));
+
+ for (ch = 0; ch < 32; ch++) {
+ buf[0][ch] = ch;
+ }
+ y = sizeof (buf[1]);
+ DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey));
+ zeromem (buf[0], sizeof (buf[0]));
+ x = sizeof (buf[0]);
+ DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey));
+ if (x != 32) {
+ fprintf(stderr, "Failed (length)");
+ return 1;
+ }
+ for (ch = 0; ch < 32; ch++) {
+ if (buf[0][ch] != ch) {
+ fprintf(stderr, "Failed (contents)");
+ return 1;
+ }
+ }
+ /* test sign_hash */
+ for (ch = 0; ch < 16; ch++) {
+ buf[0][ch] = ch;
+ }
+ x = sizeof (buf[1]);
+ DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
+ DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey));
+ buf[0][0] ^= 1;
+ DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2);
+ return 1;
+ }
+ /* test sign_hash_rfc7518 */
+ for (ch = 0; ch < 16; ch++) {
+ buf[0][ch] = ch;
+ }
+ x = sizeof (buf[1]);
+ DO(ecc_sign_hash_rfc7518(buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
+ DO(ecc_verify_hash_rfc7518(buf[1], x, buf[0], 16, &stat, &pubKey));
+ buf[0][0] ^= 1;
+ DO(ecc_verify_hash_rfc7518(buf[1], x, buf[0], 16, &stat2, &privKey));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "ecc_verify_hash_rfc7518 failed %d, %d, ", stat, stat2);
+ return 1;
+ }
+ ecc_free (&usera);
+ ecc_free (&pubKey);
+ ecc_free (&privKey);
+ }
+#ifdef LTC_ECC_SHAMIR
+ return ecc_test_shamir();
+#else
+ return 0;
+#endif
+}
+
+#else
+
+int ecc_tests(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/file_test.c b/libtomcrypt/tests/file_test.c
new file mode 100644
index 0000000..9ba607e
--- /dev/null
+++ b/libtomcrypt/tests/file_test.c
@@ -0,0 +1,115 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+/* test file related functions */
+
+#include <tomcrypt_test.h>
+
+int file_test(void)
+{
+#ifdef LTC_NO_FILE
+ return CRYPT_NOP;
+#else
+ unsigned char key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
+ unsigned char buf[200];
+ unsigned long len;
+ const char *fname = "tests/test.key";
+ FILE *in;
+ int err, isha256, iaes;
+
+ /* expected results */
+ unsigned char exp_sha256[32] = { 0x76, 0xEC, 0x7F, 0xAE, 0xBD, 0xC4, 0x2A, 0x4D, 0xE3, 0x5C, 0xA7, 0x00, 0x24, 0xC2, 0xD2, 0x73,
+ 0xE9, 0xF7, 0x85, 0x6C, 0xA6, 0x16, 0x12, 0xE8, 0x9F, 0x5F, 0x66, 0x35, 0x0B, 0xA8, 0xCF, 0x5F };
+ isha256 = find_hash("sha256");
+ iaes = find_cipher("aes");
+
+ len = sizeof(buf);
+ if ((in = fopen(fname, "rb")) == NULL) return CRYPT_FILE_NOTFOUND;
+ err = hash_filehandle(isha256, in, buf, &len);
+ fclose(in);
+ if (err != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_sha256, 32, "hash_filehandle", 1)) return 1;
+
+ len = sizeof(buf);
+ if ((err = hash_file(isha256, fname, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_sha256, 32, "hash_file", 1)) return 1;
+
+#ifdef LTC_HMAC
+ {
+ unsigned char exp_hmacsha256[32] = { 0xE4, 0x07, 0x74, 0x95, 0xF1, 0xF8, 0x5B, 0xB5, 0xF1, 0x4F, 0x7D, 0x4F, 0x59, 0x8E, 0x4B, 0xBC,
+ 0x8F, 0x68, 0xCF, 0xBA, 0x2E, 0xAD, 0xC4, 0x63, 0x9D, 0x7F, 0x02, 0x99, 0x8C, 0x08, 0xAC, 0xC0 };
+ len = sizeof(buf);
+ if ((err = hmac_file(isha256, fname, key, 32, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_hmacsha256, 32, "hmac_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_OMAC
+ {
+ unsigned char exp_omacaes[16] = { 0x50, 0xB4, 0x6C, 0x62, 0xE9, 0xCA, 0x48, 0xFC, 0x38, 0x8D, 0xF4, 0xA2, 0x7D, 0x6A, 0x1E, 0xD8 };
+ len = sizeof(buf);
+ if ((err = omac_file(iaes, key, 32, fname, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_omacaes, 16, "omac_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_PMAC
+ {
+ unsigned char exp_pmacaes[16] = { 0x7D, 0x65, 0xF0, 0x75, 0x4F, 0x8D, 0xE2, 0xB0, 0xE4, 0xFA, 0x54, 0x4E, 0x45, 0x01, 0x36, 0x1B };
+ len = sizeof(buf);
+ if ((err = pmac_file(iaes, key, 32, fname, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_pmacaes, 16, "pmac_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_XCBC
+ {
+ unsigned char exp_xcbcaes[16] = { 0x9C, 0x73, 0xA2, 0xD7, 0x90, 0xA5, 0x86, 0x25, 0x4D, 0x3C, 0x8A, 0x6A, 0x24, 0x6D, 0xD1, 0xAB };
+ len = sizeof(buf);
+ if ((err = xcbc_file(iaes, key, 32, fname, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_xcbcaes, 16, "xcbc_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_F9_MODE
+ {
+ unsigned char exp_f9aes[16] = { 0x6B, 0x6A, 0x18, 0x34, 0x13, 0x8E, 0x01, 0xEF, 0x33, 0x8E, 0x7A, 0x3F, 0x5B, 0x9A, 0xA6, 0x7A };
+ len = sizeof(buf);
+ if ((err = f9_file(iaes, key, 32, fname, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_f9aes, 16, "f9_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_POLY1305
+ {
+ unsigned char exp_poly1305[16] = { 0xD0, 0xC7, 0xFB, 0x13, 0xA8, 0x87, 0x84, 0x23, 0x21, 0xCC, 0xA9, 0x43, 0x81, 0x18, 0x75, 0xBE };
+ len = sizeof(buf);
+ if ((err = poly1305_file(fname, key, 32, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_poly1305, 16, "poly1305_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_BLAKE2SMAC
+ {
+ unsigned char exp_blake2smac[16] = { 0x4f, 0x94, 0x45, 0x15, 0xcd, 0xd1, 0xca, 0x02, 0x1a, 0x0c, 0x7a, 0xe4, 0x6d, 0x2f, 0xe8, 0xb3 };
+ len = 16;
+ if ((err = blake2smac_file(fname, key, 32, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_blake2smac, 16, "exp_blake2smac_file", 1)) return 1;
+ }
+#endif
+#ifdef LTC_BLAKE2BMAC
+ {
+ unsigned char exp_blake2bmac[16] = { 0xdf, 0x0e, 0x7a, 0xab, 0x96, 0x6b, 0x75, 0x4e, 0x52, 0x6a, 0x43, 0x96, 0xbd, 0xef, 0xab, 0x44 };
+ len = 16;
+ if ((err = blake2bmac_file(fname, key, 32, buf, &len)) != CRYPT_OK) return err;
+ if (compare_testvector(buf, len, exp_blake2bmac, 16, "exp_blake2bmac_file", 1)) return 1;
+ }
+#endif
+
+ return CRYPT_OK;
+#endif
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/katja_test.c b/libtomcrypt/tests/katja_test.c
new file mode 100644
index 0000000..ef9b27f
--- /dev/null
+++ b/libtomcrypt/tests/katja_test.c
@@ -0,0 +1,242 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MKAT) && defined(LTC_TEST_MPI)
+
+int katja_test(void)
+{
+ unsigned char in[1024], out[1024], tmp[1024];
+ katja_key key, privKey, pubKey;
+ int hash_idx, prng_idx, stat, stat2, size;
+ unsigned long kat_msgsize, len, len2, cnt;
+ static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
+
+ hash_idx = find_hash("sha1");
+ prng_idx = find_prng("yarrow");
+ if (hash_idx == -1 || prng_idx == -1) {
+ fprintf(stderr, "katja_test requires LTC_SHA1 and yarrow");
+ return 1;
+ }
+
+for (size = 1024; size <= 2048; size += 256) {
+
+ /* make 10 random key */
+ for (cnt = 0; cnt < 10; cnt++) {
+ DO(katja_make_key(&yarrow_prng, prng_idx, size/8, &key));
+ if (mp_count_bits(key.N) < size - 7) {
+ fprintf(stderr, "katja_%d key modulus has %d bits\n", size, mp_count_bits(key.N));
+
+len = mp_unsigned_bin_size(key.N);
+mp_to_unsigned_bin(key.N, tmp);
+ fprintf(stderr, "N == \n");
+for (cnt = 0; cnt < len; ) {
+ fprintf(stderr, "%02x ", tmp[cnt]);
+ if (!(++cnt & 15)) fprintf(stderr, "\n");
+}
+
+len = mp_unsigned_bin_size(key.p);
+mp_to_unsigned_bin(key.p, tmp);
+ fprintf(stderr, "p == \n");
+for (cnt = 0; cnt < len; ) {
+ fprintf(stderr, "%02x ", tmp[cnt]);
+ if (!(++cnt & 15)) fprintf(stderr, "\n");
+}
+
+len = mp_unsigned_bin_size(key.q);
+mp_to_unsigned_bin(key.q, tmp);
+ fprintf(stderr, "\nq == \n");
+for (cnt = 0; cnt < len; ) {
+ fprintf(stderr, "%02x ", tmp[cnt]);
+ if (!(++cnt & 15)) fprintf(stderr, "\n");
+}
+ fprintf(stderr, "\n");
+
+
+ return 1;
+ }
+ if (cnt != 9) {
+ katja_free(&key);
+ }
+ }
+ /* encrypt the key (without lparam) */
+ for (cnt = 0; cnt < 4; cnt++) {
+ for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) {
+ /* make a random key/msg */
+ yarrow_read(in, kat_msgsize, &yarrow_prng);
+
+ len = sizeof(out);
+ len2 = kat_msgsize;
+
+ DO(katja_encrypt_key(in, kat_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key));
+ /* change a byte */
+ out[8] ^= 1;
+ DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key));
+ /* change a byte back */
+ out[8] ^= 1;
+ if (len2 != kat_msgsize) {
+ fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2);
+ return 1;
+ }
+
+ len2 = kat_msgsize;
+ DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_decrypt_key failed");
+ return 1;
+ }
+ if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) {
+ unsigned long x;
+ fprintf(stderr, "\nkatja_decrypt_key mismatch, len %lu (second decrypt)\n", len2);
+ fprintf(stderr, "Original contents: \n");
+ for (x = 0; x < kat_msgsize; ) {
+ fprintf(stderr, "%02x ", in[x]);
+ if (!(++x % 16)) {
+ fprintf(stderr, "\n");
+ }
+ }
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Output contents: \n");
+ for (x = 0; x < kat_msgsize; ) {
+ fprintf(stderr, "%02x ", out[x]);
+ if (!(++x % 16)) {
+ fprintf(stderr, "\n");
+ }
+ }
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ }
+ }
+
+ /* encrypt the key (with lparam) */
+ for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) {
+ len = sizeof(out);
+ len2 = kat_msgsize;
+ DO(katja_encrypt_key(in, kat_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key));
+ /* change a byte */
+ out[8] ^= 1;
+ DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key));
+ if (len2 != kat_msgsize) {
+ fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2);
+ return 1;
+ }
+ /* change a byte back */
+ out[8] ^= 1;
+
+ len2 = kat_msgsize;
+ DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_decrypt_key failed");
+ return 1;
+ }
+ if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) {
+ fprintf(stderr, "katja_decrypt_key mismatch len %lu", len2);
+ return 1;
+ }
+ }
+
+#if 0
+
+ /* sign a message (unsalted, lower cholestorol and Atkins approved) now */
+ len = sizeof(out);
+ DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key));
+
+/* export key and import as both private and public */
+ len2 = sizeof(tmp);
+ DO(katja_export(tmp, &len2, PK_PRIVATE, &key));
+ DO(katja_import(tmp, len2, &privKey));
+ len2 = sizeof(tmp);
+ DO(katja_export(tmp, &len2, PK_PUBLIC, &key));
+ DO(katja_import(tmp, len2, &pubKey));
+
+ /* verify with original */
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2);
+ katja_free(&key);
+ katja_free(&pubKey);
+ katja_free(&privKey);
+ return 1;
+ }
+
+ /* verify with privKey */
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2);
+ katja_free(&key);
+ katja_free(&pubKey);
+ katja_free(&privKey);
+ return 1;
+ }
+
+ /* verify with pubKey */
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2);
+ katja_free(&key);
+ katja_free(&pubKey);
+ katja_free(&privKey);
+ return 1;
+ }
+
+ /* sign a message (salted) now (use privKey to make, pubKey to verify) */
+ len = sizeof(out);
+ DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey));
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "katja_verify_hash (salted) failed, %d, %d", stat, stat2);
+ katja_free(&key);
+ katja_free(&pubKey);
+ katja_free(&privKey);
+ return 1;
+ }
+#endif
+
+ katja_free(&key);
+ katja_free(&pubKey);
+ katja_free(&privKey);
+}
+
+ /* free the key and return */
+ return 0;
+}
+
+#else
+
+int katja_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/mac_test.c b/libtomcrypt/tests/mac_test.c
new file mode 100644
index 0000000..dec87d1
--- /dev/null
+++ b/libtomcrypt/tests/mac_test.c
@@ -0,0 +1,64 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+/* test pmac/omac/hmac */
+#include <tomcrypt_test.h>
+
+int mac_test(void)
+{
+#ifdef LTC_HMAC
+ DO(hmac_test());
+#endif
+#ifdef LTC_PMAC
+ DO(pmac_test());
+#endif
+#ifdef LTC_OMAC
+ DO(omac_test());
+#endif
+#ifdef LTC_XCBC
+ DO(xcbc_test());
+#endif
+#ifdef LTC_F9_MODE
+ DO(f9_test());
+#endif
+#ifdef LTC_EAX_MODE
+ DO(eax_test());
+#endif
+#ifdef LTC_OCB_MODE
+ DO(ocb_test());
+#endif
+#ifdef LTC_OCB3_MODE
+ DO(ocb3_test());
+#endif
+#ifdef LTC_CCM_MODE
+ DO(ccm_test());
+#endif
+#ifdef LTC_GCM_MODE
+ DO(gcm_test());
+#endif
+#ifdef LTC_PELICAN
+ DO(pelican_test());
+#endif
+#ifdef LTC_POLY1305
+ DO(poly1305_test());
+#endif
+#ifdef LTC_CHACHA20POLY1305_MODE
+ DO(chacha20poly1305_test());
+#endif
+#ifdef LTC_BLAKE2SMAC
+ DO(blake2smac_test());
+#endif
+#ifdef LTC_BLAKE2BMAC
+ DO(blake2bmac_test());
+#endif
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/misc_test.c b/libtomcrypt/tests/misc_test.c
new file mode 100644
index 0000000..b0140ce
--- /dev/null
+++ b/libtomcrypt/tests/misc_test.c
@@ -0,0 +1,33 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+int misc_test(void)
+{
+#ifdef LTC_HKDF
+ DO(hkdf_test());
+#endif
+#ifdef LTC_PKCS_5
+ DO(pkcs_5_test());
+#endif
+#ifdef LTC_BASE64
+ DO(base64_test());
+#endif
+#ifdef LTC_ADLER32
+ DO(adler32_test());
+#endif
+#ifdef LTC_CRC32
+ DO(crc32_test());
+#endif
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/modes_test.c b/libtomcrypt/tests/modes_test.c
new file mode 100644
index 0000000..96b2332
--- /dev/null
+++ b/libtomcrypt/tests/modes_test.c
@@ -0,0 +1,130 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+/* test CFB/OFB/CBC modes */
+#include <tomcrypt_test.h>
+
+int modes_test(void)
+{
+ int ret = CRYPT_NOP;
+#ifdef LTC_CBC_MODE
+ symmetric_CBC cbc;
+#endif
+#ifdef LTC_CFB_MODE
+ symmetric_CFB cfb;
+#endif
+#ifdef LTC_OFB_MODE
+ symmetric_OFB ofb;
+#endif
+#if defined(LTC_CBC_MODE) || defined(LTC_CFB_MODE) || defined(LTC_OFB_MODE)
+ unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16];
+ int cipher_idx;
+ unsigned long l;
+
+ /* make a random pt, key and iv */
+ yarrow_read(pt, 64, &yarrow_prng);
+ yarrow_read(key, 16, &yarrow_prng);
+ yarrow_read(iv, 16, &yarrow_prng);
+
+ /* get idx of AES handy */
+ cipher_idx = find_cipher("aes");
+ if (cipher_idx == -1) {
+ fprintf(stderr, "test requires AES");
+ return 1;
+ }
+#endif
+
+#ifdef LTC_F8_MODE
+ DO(ret = f8_test_mode());
+#endif
+
+#ifdef LTC_LRW_MODE
+ DO(ret = lrw_test());
+#endif
+
+#ifdef LTC_CBC_MODE
+ /* test CBC mode */
+ /* encode the block */
+ DO(ret = cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+ l = sizeof(iv2);
+ DO(ret = cbc_getiv(iv2, &l, &cbc));
+ if (l != 16 || memcmp(iv2, iv, 16)) {
+ fprintf(stderr, "cbc_getiv failed");
+ return 1;
+ }
+ DO(ret = cbc_encrypt(pt, ct, 64, &cbc));
+
+ /* decode the block */
+ DO(ret = cbc_setiv(iv2, l, &cbc));
+ zeromem(tmp, sizeof(tmp));
+ DO(ret = cbc_decrypt(ct, tmp, 64, &cbc));
+ if (memcmp(tmp, pt, 64) != 0) {
+ fprintf(stderr, "CBC failed");
+ return 1;
+ }
+#endif
+
+#ifdef LTC_CFB_MODE
+ /* test CFB mode */
+ /* encode the block */
+ DO(ret = cfb_start(cipher_idx, iv, key, 16, 0, &cfb));
+ l = sizeof(iv2);
+ DO(ret = cfb_getiv(iv2, &l, &cfb));
+ /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
+ if (l != 16) {
+ fprintf(stderr, "cfb_getiv failed");
+ return 1;
+ }
+ DO(ret = cfb_encrypt(pt, ct, 64, &cfb));
+
+ /* decode the block */
+ DO(ret = cfb_setiv(iv, l, &cfb));
+ zeromem(tmp, sizeof(tmp));
+ DO(ret = cfb_decrypt(ct, tmp, 64, &cfb));
+ if (memcmp(tmp, pt, 64) != 0) {
+ fprintf(stderr, "CFB failed");
+ return 1;
+ }
+#endif
+
+#ifdef LTC_OFB_MODE
+ /* test OFB mode */
+ /* encode the block */
+ DO(ret = ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
+ l = sizeof(iv2);
+ DO(ret = ofb_getiv(iv2, &l, &ofb));
+ if (l != 16 || memcmp(iv2, iv, 16)) {
+ fprintf(stderr, "ofb_getiv failed");
+ return 1;
+ }
+ DO(ret = ofb_encrypt(pt, ct, 64, &ofb));
+
+ /* decode the block */
+ DO(ret = ofb_setiv(iv2, l, &ofb));
+ zeromem(tmp, sizeof(tmp));
+ DO(ret = ofb_decrypt(ct, tmp, 64, &ofb));
+ if (memcmp(tmp, pt, 64) != 0) {
+ fprintf(stderr, "OFB failed");
+ return 1;
+ }
+#endif
+
+#if defined(LTC_CTR_MODE) && defined(LTC_RIJNDAEL)
+ DO(ret = ctr_test());
+#endif
+
+#ifdef LTC_XTS_MODE
+ DO(ret = xts_test());
+#endif
+
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/mpi_test.c b/libtomcrypt/tests/mpi_test.c
new file mode 100644
index 0000000..9bb73ae
--- /dev/null
+++ b/libtomcrypt/tests/mpi_test.c
@@ -0,0 +1,147 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MPI) && defined(LTC_TEST_MPI)
+static int _radix_to_bin_test(void)
+{
+ /* RADIX 16 */
+ const char *ghex = "2";
+ const char *phex = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22"
+ "514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6"
+ "F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"
+ "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E8603"
+ "9B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+ "15728E5A8AACAA68FFFFFFFFFFFFFFFF";
+ const char *xhex = "A6681ADC386CE944C3DED9A7301DCC9C518250E3EDB62F959198F8DC0057DD6FB57ABAFD788198B1";
+ const char *yhex = "39046632C834418DFA07B3091538B614D1FB5DBB785C0FBEA3B98B295BC0CD076A88D9452141A269"
+ "E8BAEB1DD654EBA03A5705318D129754CDF4003A8C399240FBB8F162490F6F0DC70E414B6FEE8808"
+ "6AFAA48E9F3A248EDC093452663D34E0E809D4F6BADBB36F80B6813EBF7C3281B862209E5604BDEA"
+ "8B8F5F7BFDC3EEB7ADB73048289BCEA0F5A5CDEE7DF91CD1F0BA632F06DBE9BA7EF014B84B02D497"
+ "CA7D0C60F734752A649DA496946B4E531B30D9F82EDD855636C0B0F2AE232E4186454E8887BB423E"
+ "32A5A2495EACBA99620ACD03A38345EBB6735E62330A8EE9AA6C8370410F5CD45AF37EE90A0DA95B"
+ "E96FC939E88FE0BD2CD09FC8F524208C";
+ /* RADIX 47 */
+ const char *gr47 = "2";
+ const char *pr47 = "F27Mg1SadOFIRbDOJ5dHgHiVF02Z1LHHQ6G5SLG2U8aTdfH1ETk4GARRE7WW99dBUBLb9e2OHFIaSM1A"
+ "ag2LNNjgYa9I9CjQGJihL3J7A2SGQe8j5Ch8EHMj5jVbAYDiQKhhPhM6Hc56fKS40GUfJkGO7KJ6EXZQ"
+ "VgbSa2AkPC65F91g0PaYie8AGNVaFKaV9HOQf3ia1iW4i6eCOB9CcBbH7TbQij8AEgjZ0VRBcLKc6UYO"
+ "1Zc3I2Jc0h1H2HBEH8ONI3OYBbaPV6XhAd8WCc60D0RDBU3H9U7cWL28a0c90XNO0dh5RXEFBbUCE2ZG"
+ "gh9XQSVIHkVbFIS5F5IGVOkiWAVc9i8BHB2V0UbGW6UdRTZVV";
+ const char *xr47 = "6bhO7O9NWFRgEMjdU0Y5POj3c1JP15MYEdIg3FO1PEjUY2aGYNSXcaF01R";
+ const char *yr47 = "3GNPNWEYfKML1cIbI7Cc1Z0O7aQLJgB734dO2i56LLYDdI4gHYk2GAbQH2WI97hNeC7dj3fPEH8I9gV9"
+ "U323AXj1AJXbFPFIHGOTdC29QUUeH2SSc6NWhfQDDXd5Q5iXCKEAUGX3SKcNFIfVOYJgZCLjfHYQdgOQ"
+ "GCjKNgbEV7Hj34MU3b79iANX2DbMYfb9iGi78BWH2HYAd7IAhk7U0OYGHKJX1bIUUj1KBLhAUg46GaER"
+ "G9W3ARMfBCj6kSdDF9TdkWAjWTDj722IeVJERC4bKU2VDFG20kDhCMF985efD1SS8DfXcdCHF1kDUkSA"
+ "884FHYiFEPkaagQOBQaN9BNaEHNbbd002DCIIX5eMP4HgPJPF";
+ /* RADIX 64 */
+ const char *gr64 = "2";
+ const char *pr64 = "3//////////yaFsg8XQC8qnCPYYu3S7D4f0au8YcVCT08BlgOx4viYKKe8UOuq1DtlbHcppJf36p0h2c"
+ "toNnGtJ+4rRMrHmaNaXRLsObv+nlHCGkccD+rh2/zSjlG6j+tkE6lxMecVfQwV915yIn/cIIXcKUpaMp"
+ "t207oueME/1PZQI3OSLTEQQHO/gFqapr+3PLqZtAEjbXnYyrOWXLAxdjKf1t2Mbcrd33LEIhoO1F5qR0"
+ "ZA625yCf1UHYuspZlZddSi60w60vidWwBi1wAFjSLTy6zCKidUAylsbLWN63cLINpgbMhb5T8c69Zw1H"
+ "0LSevQYgogQF//////////";
+ const char *xr64 = "2cQ1hSE6pfHCFUsQSm7SoSKO9Gu+ssBvMHcFZS05VTRxLwklruWPYn";
+ const char *yr64 = "v16Ooo3H1ZVe7imaLEBOKqVjTktXS3xwZkOifMy3D1sg8sKKXGQ9fwBhh7TPKww0wLmKnZHANLCtq03g"
+ "CEP90+xZnOaaFRmt73a5BR+w826hwf8wVEYIEt0aqKcOzDE3e2TJskjkpRu2sWJw/V3A1k68WdbO4lUg"
+ "BZrzx/SFkjwstC4WecywWzQNDxdtv7D7mkcCl1jlfkdxm5BXB0jINodqCOFSqTIfadQIMb6jEKnimsVW"
+ "ktOLMDi2myguZBa66HKw8Xxj2FZAbeabUhBgPOWhD0wE3HUksSrvYCmgEwQfiWt113rpKMlD+wGeDgLl"
+ "fRyavw8/WlIpGdyZr922C";
+ /* RADIX 256 */
+ unsigned char gbin[] = { 0x02 };
+ unsigned char pbin[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+ unsigned char xbin[] = {
+ 0xA6, 0x68, 0x1A, 0xDC, 0x38, 0x6C, 0xE9, 0x44, 0xC3, 0xDE, 0xD9, 0xA7, 0x30, 0x1D, 0xCC, 0x9C,
+ 0x51, 0x82, 0x50, 0xE3, 0xED, 0xB6, 0x2F, 0x95, 0x91, 0x98, 0xF8, 0xDC, 0x00, 0x57, 0xDD, 0x6F,
+ 0xB5, 0x7A, 0xBA, 0xFD, 0x78, 0x81, 0x98, 0xB1
+ };
+ unsigned char ybin[] = {
+ 0x39, 0x04, 0x66, 0x32, 0xC8, 0x34, 0x41, 0x8D, 0xFA, 0x07, 0xB3, 0x09, 0x15, 0x38, 0xB6, 0x14,
+ 0xD1, 0xFB, 0x5D, 0xBB, 0x78, 0x5C, 0x0F, 0xBE, 0xA3, 0xB9, 0x8B, 0x29, 0x5B, 0xC0, 0xCD, 0x07,
+ 0x6A, 0x88, 0xD9, 0x45, 0x21, 0x41, 0xA2, 0x69, 0xE8, 0xBA, 0xEB, 0x1D, 0xD6, 0x54, 0xEB, 0xA0,
+ 0x3A, 0x57, 0x05, 0x31, 0x8D, 0x12, 0x97, 0x54, 0xCD, 0xF4, 0x00, 0x3A, 0x8C, 0x39, 0x92, 0x40,
+ 0xFB, 0xB8, 0xF1, 0x62, 0x49, 0x0F, 0x6F, 0x0D, 0xC7, 0x0E, 0x41, 0x4B, 0x6F, 0xEE, 0x88, 0x08,
+ 0x6A, 0xFA, 0xA4, 0x8E, 0x9F, 0x3A, 0x24, 0x8E, 0xDC, 0x09, 0x34, 0x52, 0x66, 0x3D, 0x34, 0xE0,
+ 0xE8, 0x09, 0xD4, 0xF6, 0xBA, 0xDB, 0xB3, 0x6F, 0x80, 0xB6, 0x81, 0x3E, 0xBF, 0x7C, 0x32, 0x81,
+ 0xB8, 0x62, 0x20, 0x9E, 0x56, 0x04, 0xBD, 0xEA, 0x8B, 0x8F, 0x5F, 0x7B, 0xFD, 0xC3, 0xEE, 0xB7,
+ 0xAD, 0xB7, 0x30, 0x48, 0x28, 0x9B, 0xCE, 0xA0, 0xF5, 0xA5, 0xCD, 0xEE, 0x7D, 0xF9, 0x1C, 0xD1,
+ 0xF0, 0xBA, 0x63, 0x2F, 0x06, 0xDB, 0xE9, 0xBA, 0x7E, 0xF0, 0x14, 0xB8, 0x4B, 0x02, 0xD4, 0x97,
+ 0xCA, 0x7D, 0x0C, 0x60, 0xF7, 0x34, 0x75, 0x2A, 0x64, 0x9D, 0xA4, 0x96, 0x94, 0x6B, 0x4E, 0x53,
+ 0x1B, 0x30, 0xD9, 0xF8, 0x2E, 0xDD, 0x85, 0x56, 0x36, 0xC0, 0xB0, 0xF2, 0xAE, 0x23, 0x2E, 0x41,
+ 0x86, 0x45, 0x4E, 0x88, 0x87, 0xBB, 0x42, 0x3E, 0x32, 0xA5, 0xA2, 0x49, 0x5E, 0xAC, 0xBA, 0x99,
+ 0x62, 0x0A, 0xCD, 0x03, 0xA3, 0x83, 0x45, 0xEB, 0xB6, 0x73, 0x5E, 0x62, 0x33, 0x0A, 0x8E, 0xE9,
+ 0xAA, 0x6C, 0x83, 0x70, 0x41, 0x0F, 0x5C, 0xD4, 0x5A, 0xF3, 0x7E, 0xE9, 0x0A, 0x0D, 0xA9, 0x5B,
+ 0xE9, 0x6F, 0xC9, 0x39, 0xE8, 0x8F, 0xE0, 0xBD, 0x2C, 0xD0, 0x9F, 0xC8, 0xF5, 0x24, 0x20, 0x8C
+ };
+
+ struct {
+ int radix;
+ const void* g; int glen;
+ const void* p; int plen;
+ const void* x; int xlen;
+ const void* y; int ylen;
+ } test[4] = {
+ { 256, gbin, sizeof(gbin), pbin, sizeof(pbin), xbin, sizeof(xbin), ybin, sizeof(ybin) },
+ { 16, ghex, strlen(ghex)+1, phex, strlen(phex)+1, xhex, strlen(xhex)+1, yhex, strlen(yhex)+1 },
+ { 47, gr47, strlen(gr47)+1, pr47, strlen(pr47)+1, xr47, strlen(xr47)+1, yr47, strlen(yr47)+1 },
+ { 64, gr64, strlen(gr64)+1, pr64, strlen(pr64)+1, xr64, strlen(xr64)+1, yr64, strlen(yr64)+1 },
+ };
+ int i, j;
+ unsigned char key_parts[4][256];
+ unsigned long key_lens[4];
+
+ for (i = 1; i < 4; i++) {
+ for (j = 0; j < 4; ++j) {
+ key_lens[j] = sizeof(key_parts[j]);
+ }
+ DO(radix_to_bin(test[i].x, test[i].radix, key_parts[0], &key_lens[0]));
+ DO(radix_to_bin(test[i].y, test[i].radix, key_parts[1], &key_lens[1]));
+ DO(radix_to_bin(test[i].p, test[i].radix, key_parts[2], &key_lens[2]));
+ DO(radix_to_bin(test[i].g, test[i].radix, key_parts[3], &key_lens[3]));
+
+ if (compare_testvector(key_parts[0], key_lens[0], test[0].x, test[0].xlen, "radix_to_bin(x)", i)) return CRYPT_FAIL_TESTVECTOR;
+ if (compare_testvector(key_parts[1], key_lens[1], test[0].y, test[0].ylen, "radix_to_bin(y)", i)) return CRYPT_FAIL_TESTVECTOR;
+ if (compare_testvector(key_parts[2], key_lens[2], test[0].p, test[0].plen, "radix_to_bin(p)", i)) return CRYPT_FAIL_TESTVECTOR;
+ if (compare_testvector(key_parts[3], key_lens[3], test[0].g, test[0].glen, "radix_to_bin(g)", i)) return CRYPT_FAIL_TESTVECTOR;
+ }
+ return CRYPT_OK;
+}
+
+int mpi_test(void)
+{
+ return _radix_to_bin_test();
+}
+#else
+int mpi_test(void)
+{
+ return CRYPT_NOP;
+}
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/multi_test.c b/libtomcrypt/tests/multi_test.c
new file mode 100644
index 0000000..4b4da08
--- /dev/null
+++ b/libtomcrypt/tests/multi_test.c
@@ -0,0 +1,237 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+/* test the multi helpers... */
+#include <tomcrypt_test.h>
+
+int multi_test(void)
+{
+ unsigned char key[32] = { 0 };
+ unsigned char buf[2][MAXBLOCKSIZE];
+ unsigned long len, len2;
+
+/* register algos */
+ register_hash(&sha256_desc);
+ register_cipher(&aes_desc);
+
+/* HASH testing */
+ len = sizeof(buf[0]);
+ hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+#ifdef LTC_HMAC
+ len = sizeof(buf[0]);
+ hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_OMAC
+ len = sizeof(buf[0]);
+ omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_PMAC
+ len = sizeof(buf[0]);
+ pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_XCBC
+ len = sizeof(buf[0]);
+ xcbc_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_F9
+ len = sizeof(buf[0]);
+ f9_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_PELICAN
+ /* TODO: there is no pelican_memory_multi(..) */
+#endif
+
+#ifdef LTC_POLY1305
+ len = sizeof(buf[0]);
+ poly1305_memory(key, 32, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = sizeof(buf[0]);
+ poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = sizeof(buf[0]);
+ poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_BLAKE2SMAC
+ len = 32;
+ blake2smac_memory(key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = 32;
+ blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = 32;
+ blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = 32;
+ blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+#ifdef LTC_BLAKE2BMAC
+ len = 64;
+ blake2bmac_memory(key, 16, (unsigned char*)"hello", 5, buf[0], &len);
+ len2 = 64;
+ blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = 64;
+ blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ len2 = 64;
+ blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
+ if (len != len2 || memcmp(buf[0], buf[1], len)) {
+ printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+#endif
+
+ return CRYPT_OK;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/no_prng.c b/libtomcrypt/tests/no_prng.c
new file mode 100644
index 0000000..9f2bee3
--- /dev/null
+++ b/libtomcrypt/tests/no_prng.c
@@ -0,0 +1,185 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt.h"
+
+/**
+ @file no_prng.c
+ NO PRNG, Steffen Jaeckel
+*/
+
+#ifdef LTC_PKCS_1
+
+typedef struct
+{
+ struct ltc_prng_descriptor desc;
+ char name[64];
+ unsigned char entropy[1024];
+ unsigned long len;
+ unsigned long offset;
+} no_prng_desc_t;
+
+/**
+ Start the PRNG
+ @param prng [out] The PRNG state to initialize
+ @return CRYPT_OK if successful
+*/
+int no_prng_start(prng_state *prng)
+{
+ no_prng_desc_t *no_prng = (no_prng_desc_t*) prng;
+ LTC_ARGCHK(no_prng != NULL);
+ LTC_ARGCHK(no_prng->name == (char*)no_prng + offsetof(no_prng_desc_t, name));
+ no_prng->len = 0;
+ no_prng->offset = 0;
+
+ return CRYPT_OK;
+}
+
+/**
+ Add entropy to the PRNG state
+ @param in The data to add
+ @param inlen Length of the data to add
+ @param prng PRNG state to update
+ @return CRYPT_OK if successful
+*/
+int no_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
+{
+ no_prng_desc_t *no_prng = (no_prng_desc_t*) prng;
+ LTC_ARGCHK(no_prng != NULL);
+ LTC_ARGCHK(no_prng->name == (char*)no_prng + offsetof(no_prng_desc_t, name));
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(inlen <= sizeof(no_prng->entropy));
+
+ no_prng->len = MIN(inlen, sizeof(no_prng->entropy));
+ memcpy(no_prng->entropy, in, no_prng->len);
+ no_prng->offset = 0;
+
+ return CRYPT_OK;
+
+}
+
+/**
+ Make the PRNG ready to read from
+ @param prng The PRNG to make active
+ @return CRYPT_OK if successful
+*/
+int no_prng_ready(prng_state *prng)
+{
+ LTC_ARGCHK(prng != NULL);
+
+ return CRYPT_OK;
+}
+
+/**
+ Read from the PRNG
+ @param out Destination
+ @param outlen Length of output
+ @param prng The active PRNG to read from
+ @return Number of octets read
+*/
+unsigned long no_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
+{
+ no_prng_desc_t *no_prng = (no_prng_desc_t*) prng;
+ LTC_ARGCHK(no_prng != NULL);
+ LTC_ARGCHK(no_prng->name == (char*)no_prng + offsetof(no_prng_desc_t, name));
+ LTC_ARGCHK(out != NULL);
+
+ outlen = MIN(outlen, no_prng->len - no_prng->offset);
+ memcpy(out, &no_prng->entropy[no_prng->offset], outlen);
+ no_prng->offset += outlen;
+
+ return outlen;
+}
+
+/**
+ Terminate the PRNG
+ @param prng The PRNG to terminate
+ @return CRYPT_OK if successful
+*/
+int no_prng_done(prng_state *prng)
+{
+ LTC_UNUSED_PARAM(prng);
+ return CRYPT_OK;
+}
+
+/**
+ Export the PRNG state
+ @param out [out] Destination
+ @param outlen [in/out] Max size and resulting size of the state
+ @param prng The PRNG to export
+ @return CRYPT_OK if successful
+*/
+int no_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
+{
+ LTC_UNUSED_PARAM(out);
+ LTC_UNUSED_PARAM(outlen);
+ LTC_UNUSED_PARAM(prng);
+ return CRYPT_OK;
+}
+
+/**
+ Import a PRNG state
+ @param in The PRNG state
+ @param inlen Size of the state
+ @param prng The PRNG to import
+ @return CRYPT_OK if successful
+*/
+int no_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
+{
+ LTC_UNUSED_PARAM(in);
+ LTC_UNUSED_PARAM(inlen);
+ LTC_UNUSED_PARAM(prng);
+ return CRYPT_OK;
+}
+
+/**
+ PRNG self-test
+ @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
+*/
+int no_prng_test(void)
+{
+ return CRYPT_OK;
+}
+
+static const struct ltc_prng_descriptor no_prng_desc =
+{
+ NULL, 0,
+ &no_prng_start,
+ &no_prng_add_entropy,
+ &no_prng_ready,
+ &no_prng_read,
+ &no_prng_done,
+ &no_prng_export,
+ &no_prng_import,
+ &no_prng_test
+};
+
+struct ltc_prng_descriptor* no_prng_desc_get(void)
+{
+ no_prng_desc_t* no_prng = XMALLOC(sizeof(*no_prng));
+ LTC_ARGCHK(no_prng != NULL);
+ XMEMCPY(&no_prng->desc, &no_prng_desc, sizeof(no_prng_desc));
+ LTC_ARGCHK(snprintf(no_prng->name, sizeof(no_prng->name), "no_prng@%p", no_prng) < (int)sizeof(no_prng->name));
+ no_prng->desc.name = no_prng->name;
+ return &no_prng->desc;
+}
+
+void no_prng_desc_free(struct ltc_prng_descriptor* prng)
+{
+ no_prng_desc_t *no_prng = (no_prng_desc_t*) prng;
+ LTC_ARGCHK(no_prng != NULL);
+ LTC_ARGCHK(no_prng->name == (char*)no_prng + offsetof(no_prng_desc_t, name));
+ XFREE(no_prng);
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/pkcs_1_eme_test.c b/libtomcrypt/tests/pkcs_1_eme_test.c
new file mode 100644
index 0000000..79ea4da
--- /dev/null
+++ b/libtomcrypt/tests/pkcs_1_eme_test.c
@@ -0,0 +1,78 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_PKCS_1) && defined(LTC_TEST_MPI)
+
+#include "../notes/rsa-testvectors/pkcs1v15crypt-vectors.c"
+
+
+
+int pkcs_1_eme_test(void)
+{
+ struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get();
+ int prng_idx = register_prng(no_prng_desc);
+ int hash_idx = find_hash("sha1");
+ unsigned int i;
+ unsigned int j;
+
+ DO(prng_is_valid(prng_idx));
+ DO(hash_is_valid(hash_idx));
+
+ for (i = 0; i < sizeof(testcases_eme)/sizeof(testcases_eme[0]); ++i) {
+ testcase_t* t = &testcases_eme[i];
+ rsa_key k, *key = &k;
+ DOX(mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
+ &key->dP, &key->qP, &key->p, &key->q, NULL), t->name);
+
+ DOX(mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name);
+ DOX(mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name);
+ DOX(mp_read_unsigned_bin(key->N, t->rsa.n, t->rsa.n_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dQ, t->rsa.dQ, t->rsa.dQ_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dP, t->rsa.dP, t->rsa.dP_l), t->name);
+ DOX(mp_read_unsigned_bin(key->qP, t->rsa.qInv, t->rsa.qInv_l), t->name);
+ DOX(mp_read_unsigned_bin(key->q, t->rsa.q, t->rsa.q_l), t->name);
+ DOX(mp_read_unsigned_bin(key->p, t->rsa.p, t->rsa.p_l), t->name);
+ key->type = PK_PRIVATE;
+
+ for (j = 0; j < sizeof(t->data)/sizeof(t->data[0]); ++j) {
+ rsaData_t* s = &t->data[j];
+ unsigned char buf[256], obuf[256];
+ unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
+ int stat;
+ prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (prng_state*)no_prng_desc);
+ DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (prng_state*)no_prng_desc, prng_idx, -1, LTC_PKCS_1_V1_5, key), s->name);
+ DOX(obuflen == (unsigned long)s->o3_l?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(memcmp(s->o3, obuf, s->o3_l)==0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, LTC_PKCS_1_V1_5, &stat, key), s->name);
+ DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ } /* for */
+
+ mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
+ } /* for */
+
+ unregister_prng(no_prng_desc);
+ no_prng_desc_free(no_prng_desc);
+
+ return 0;
+}
+
+#else
+
+int pkcs_1_eme_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/pkcs_1_emsa_test.c b/libtomcrypt/tests/pkcs_1_emsa_test.c
new file mode 100644
index 0000000..1b22e43
--- /dev/null
+++ b/libtomcrypt/tests/pkcs_1_emsa_test.c
@@ -0,0 +1,72 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_PKCS_1) && defined(LTC_TEST_MPI)
+
+#include "../notes/rsa-testvectors/pkcs1v15sign-vectors.c"
+
+
+
+int pkcs_1_emsa_test(void)
+{
+ int hash_idx = find_hash("sha1");
+ unsigned int i;
+ unsigned int j;
+
+ DO(hash_is_valid(hash_idx));
+
+ for (i = 0; i < sizeof(testcases_emsa)/sizeof(testcases_emsa[0]); ++i) {
+ testcase_t* t = &testcases_emsa[i];
+ rsa_key k, *key = &k;
+ DOX(mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
+ &key->dP, &key->qP, &key->p, &key->q, NULL), t->name);
+
+ DOX(mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name);
+ DOX(mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name);
+ DOX(mp_read_unsigned_bin(key->N, t->rsa.n, t->rsa.n_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dQ, t->rsa.dQ, t->rsa.dQ_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dP, t->rsa.dP, t->rsa.dP_l), t->name);
+ DOX(mp_read_unsigned_bin(key->qP, t->rsa.qInv, t->rsa.qInv_l), t->name);
+ DOX(mp_read_unsigned_bin(key->q, t->rsa.q, t->rsa.q_l), t->name);
+ DOX(mp_read_unsigned_bin(key->p, t->rsa.p, t->rsa.p_l), t->name);
+ key->type = PK_PRIVATE;
+
+ for (j = 0; j < sizeof(t->data)/sizeof(t->data[0]); ++j) {
+ rsaData_t* s = &t->data[j];
+ unsigned char buf[20], obuf[256];
+ unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
+ int stat;
+ DOX(hash_memory(hash_idx, s->o1, s->o1_l, buf, &buflen), s->name);
+ DOX(rsa_sign_hash_ex(buf, buflen, obuf, &obuflen, LTC_PKCS_1_V1_5, NULL, -1, hash_idx, 0, key), s->name);
+ DOX(obuflen == (unsigned long)s->o2_l?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(memcmp(s->o2, obuf, s->o2_l)==0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(rsa_verify_hash_ex(obuf, obuflen, buf, buflen, LTC_PKCS_1_V1_5, hash_idx, 0, &stat, key), s->name);
+ DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ } /* for */
+
+ mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
+ } /* for */
+
+ return 0;
+}
+
+#else
+
+int pkcs_1_emsa_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/pkcs_1_oaep_test.c b/libtomcrypt/tests/pkcs_1_oaep_test.c
new file mode 100644
index 0000000..84e5520
--- /dev/null
+++ b/libtomcrypt/tests/pkcs_1_oaep_test.c
@@ -0,0 +1,78 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_PKCS_1) && defined(LTC_TEST_MPI)
+
+#include "../notes/rsa-testvectors/oaep-vect.c"
+
+
+
+int pkcs_1_oaep_test(void)
+{
+ struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get();
+ int prng_idx = register_prng(no_prng_desc);
+ int hash_idx = find_hash("sha1");
+ unsigned int i;
+ unsigned int j;
+
+ DO(prng_is_valid(prng_idx));
+ DO(hash_is_valid(hash_idx));
+
+ for (i = 0; i < sizeof(testcases_oaep)/sizeof(testcases_oaep[0]); ++i) {
+ testcase_t* t = &testcases_oaep[i];
+ rsa_key k, *key = &k;
+ DOX(mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
+ &key->dP, &key->qP, &key->p, &key->q, NULL), t->name);
+
+ DOX(mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name);
+ DOX(mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name);
+ DOX(mp_read_unsigned_bin(key->N, t->rsa.n, t->rsa.n_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dQ, t->rsa.dQ, t->rsa.dQ_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dP, t->rsa.dP, t->rsa.dP_l), t->name);
+ DOX(mp_read_unsigned_bin(key->qP, t->rsa.qInv, t->rsa.qInv_l), t->name);
+ DOX(mp_read_unsigned_bin(key->q, t->rsa.q, t->rsa.q_l), t->name);
+ DOX(mp_read_unsigned_bin(key->p, t->rsa.p, t->rsa.p_l), t->name);
+ key->type = PK_PRIVATE;
+
+ for (j = 0; j < sizeof(t->data)/sizeof(t->data[0]); ++j) {
+ rsaData_t* s = &t->data[j];
+ unsigned char buf[256], obuf[256];
+ unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
+ int stat;
+ prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (prng_state*)no_prng_desc);
+ DOX(rsa_encrypt_key(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (prng_state*)no_prng_desc, prng_idx, hash_idx, key), s->name);
+ DOX(obuflen == (unsigned long)s->o3_l?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(memcmp(s->o3, obuf, s->o3_l)==0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(rsa_decrypt_key(obuf, obuflen, buf, &buflen, NULL, 0, hash_idx, &stat, key), s->name);
+ DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ } /* for */
+
+ mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
+ } /* for */
+
+ unregister_prng(no_prng_desc);
+ no_prng_desc_free(no_prng_desc);
+
+ return 0;
+}
+
+#else
+
+int pkcs_1_oaep_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/pkcs_1_pss_test.c b/libtomcrypt/tests/pkcs_1_pss_test.c
new file mode 100644
index 0000000..2bf42b6
--- /dev/null
+++ b/libtomcrypt/tests/pkcs_1_pss_test.c
@@ -0,0 +1,79 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_PKCS_1) && defined(LTC_TEST_MPI)
+
+#include "../notes/rsa-testvectors/pss-vect.c"
+
+
+
+int pkcs_1_pss_test(void)
+{
+ struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get();
+ int prng_idx = register_prng(no_prng_desc);
+ int hash_idx = find_hash("sha1");
+ unsigned int i;
+ unsigned int j;
+
+ DO(prng_is_valid(prng_idx));
+ DO(hash_is_valid(hash_idx));
+
+ for (i = 0; i < sizeof(testcases_pss)/sizeof(testcases_pss[0]); ++i) {
+ testcase_t* t = &testcases_pss[i];
+ rsa_key k, *key = &k;
+ DOX(mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
+ &key->dP, &key->qP, &key->p, &key->q, NULL), t->name);
+
+ DOX(mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name);
+ DOX(mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name);
+ DOX(mp_read_unsigned_bin(key->N, t->rsa.n, t->rsa.n_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dQ, t->rsa.dQ, t->rsa.dQ_l), t->name);
+ DOX(mp_read_unsigned_bin(key->dP, t->rsa.dP, t->rsa.dP_l), t->name);
+ DOX(mp_read_unsigned_bin(key->qP, t->rsa.qInv, t->rsa.qInv_l), t->name);
+ DOX(mp_read_unsigned_bin(key->q, t->rsa.q, t->rsa.q_l), t->name);
+ DOX(mp_read_unsigned_bin(key->p, t->rsa.p, t->rsa.p_l), t->name);
+ key->type = PK_PRIVATE;
+
+ for (j = 0; j < sizeof(t->data)/sizeof(t->data[0]); ++j) {
+ rsaData_t* s = &t->data[j];
+ unsigned char buf[20], obuf[256];
+ unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf);
+ int stat;
+ prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (prng_state*)no_prng_desc);
+ DOX(hash_memory(hash_idx, s->o1, s->o1_l, buf, &buflen), s->name);
+ DOX(rsa_sign_hash(buf, buflen, obuf, &obuflen, (prng_state*)no_prng_desc, prng_idx, hash_idx, s->o2_l, key), s->name);
+ DOX(obuflen == (unsigned long)s->o3_l?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(memcmp(s->o3, obuf, s->o3_l)==0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ DOX(rsa_verify_hash(obuf, obuflen, buf, buflen, hash_idx, s->o2_l, &stat, key), s->name);
+ DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name);
+ } /* for */
+
+ mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
+ } /* for */
+
+ unregister_prng(no_prng_desc);
+ no_prng_desc_free(no_prng_desc);
+
+ return 0;
+}
+
+#else
+
+int pkcs_1_pss_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/pkcs_1_test.c b/libtomcrypt/tests/pkcs_1_test.c
new file mode 100644
index 0000000..19bc97a
--- /dev/null
+++ b/libtomcrypt/tests/pkcs_1_test.c
@@ -0,0 +1,106 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#ifdef LTC_PKCS_1
+
+#ifdef LTC_TEST_REAL_RAND
+#define LTC_TEST_RAND_SEED time(NULL)
+#else
+#define LTC_TEST_RAND_SEED 23
+#endif
+
+int pkcs_1_test(void)
+{
+ unsigned char buf[3][128];
+ int res1, res2, res3, prng_idx, hash_idx;
+ unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen;
+ static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
+
+ /* get hash/prng */
+ hash_idx = find_hash("sha1");
+ prng_idx = find_prng("yarrow");
+
+ if (hash_idx == -1 || prng_idx == -1) {
+ fprintf(stderr, "pkcs_1 tests require sha1/yarrow");
+ return 1;
+ }
+
+ srand(LTC_TEST_RAND_SEED);
+ /* do many tests */
+ for (x = 0; x < 100; x++) {
+ zeromem(buf, sizeof(buf));
+
+ /* make a dummy message (of random length) */
+ l3 = (rand() & 31) + 8;
+ for (y = 0; y < l3; y++) buf[0][y] = rand() & 255;
+
+ /* pick a random lparam len [0..16] */
+ lparamlen = abs(rand()) % 17;
+
+ /* pick a random saltlen 0..16 */
+ saltlen = abs(rand()) % 17;
+
+ /* PKCS #1 v2.0 supports modlens not multiple of 8 */
+ modlen = 800 + (abs(rand()) % 224);
+
+ /* encode it */
+ l1 = sizeof(buf[1]);
+ DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1));
+
+ /* decode it */
+ l2 = sizeof(buf[2]);
+ DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
+
+ if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
+ fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
+ fprintf(stderr, "ORIGINAL:\n");
+ for (x = 0; x < l3; x++) {
+ fprintf(stderr, "%02x ", buf[0][x]);
+ }
+ fprintf(stderr, "\nRESULT:\n");
+ for (x = 0; x < l2; x++) {
+ fprintf(stderr, "%02x ", buf[2][x]);
+ }
+ fprintf(stderr, "\n\n");
+ return 1;
+ }
+
+ /* test PSS */
+ l1 = sizeof(buf[1]);
+ DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &yarrow_prng, prng_idx, hash_idx, modlen, buf[1], &l1));
+ DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1));
+
+ buf[0][i1 = abs(rand()) % l3] ^= 1;
+ DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2));
+
+ buf[0][i1] ^= 1;
+ buf[1][i2 = abs(rand()) % (l1 - 1)] ^= 1;
+ pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3);
+ if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
+ fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#else
+
+int pkcs_1_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/prng_test.c b/libtomcrypt/tests/prng_test.c
new file mode 100644
index 0000000..e88ff92
--- /dev/null
+++ b/libtomcrypt/tests/prng_test.c
@@ -0,0 +1,90 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#ifdef LTC_PRNG_ENABLE_LTC_RNG
+
+static unsigned long my_test_rng_read;
+
+static unsigned long my_test_rng(unsigned char *buf, unsigned long len,
+ void (*callback)(void))
+{
+ unsigned long n;
+ LTC_UNUSED_PARAM(callback);
+ for (n = 0; n < len; ++n) {
+ buf[n] = 4;
+ }
+ my_test_rng_read += n;
+ return n;
+}
+
+#endif
+
+int prng_test(void)
+{
+ int err = CRYPT_NOP;
+ int x;
+ unsigned char buf[4096] = { 0 };
+ unsigned long n, one;
+ prng_state nprng;
+
+#ifdef LTC_PRNG_ENABLE_LTC_RNG
+ unsigned long before;
+
+ unsigned long (*previous)(unsigned char *, unsigned long , void (*)(void)) = ltc_rng;
+ ltc_rng = my_test_rng;
+
+ before = my_test_rng_read;
+
+ if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) {
+ fprintf(stderr, "rng_make_prng with 'my_test_rng' failed: %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ if (before == my_test_rng_read) {
+ fprintf(stderr, "somehow there was no read from the ltc_rng! %lu == %lu\n", before, my_test_rng_read);
+ exit(EXIT_FAILURE);
+ }
+
+ ltc_rng = previous;
+#endif
+
+ /* test prngs (test, import/export) */
+ for (x = 0; prng_descriptor[x].name != NULL; x++) {
+ if(strstr(prng_descriptor[x].name, "no_prng") == prng_descriptor[x].name) continue;
+ err = CRYPT_OK;
+ DOX(prng_descriptor[x].test(), prng_descriptor[x].name);
+ DOX(prng_descriptor[x].start(&nprng), prng_descriptor[x].name);
+ DOX(prng_descriptor[x].add_entropy((unsigned char *)"helloworld12", 12, &nprng), prng_descriptor[x].name);
+ DOX(prng_descriptor[x].ready(&nprng), prng_descriptor[x].name);
+ n = sizeof(buf);
+ if (strcmp(prng_descriptor[x].name, "sprng")) {
+ one = 1;
+ if (prng_descriptor[x].pexport(buf, &one, &nprng) != CRYPT_BUFFER_OVERFLOW) {
+ fprintf(stderr, "Error testing pexport with a short buffer (%s)\n", prng_descriptor[x].name);
+ return CRYPT_ERROR;
+ }
+ }
+ DOX(prng_descriptor[x].pexport(buf, &n, &nprng), prng_descriptor[x].name);
+ prng_descriptor[x].done(&nprng);
+ DOX(prng_descriptor[x].pimport(buf, n, &nprng), prng_descriptor[x].name);
+ DOX(prng_descriptor[x].pimport(buf, 4096, &nprng), prng_descriptor[x].name); /* try to import larger data */
+ DOX(prng_descriptor[x].ready(&nprng), prng_descriptor[x].name);
+ if (prng_descriptor[x].read(buf, 100, &nprng) != 100) {
+ fprintf(stderr, "Error reading from imported PRNG (%s)!\n", prng_descriptor[x].name);
+ return CRYPT_ERROR;
+ }
+ prng_descriptor[x].done(&nprng);
+ }
+ return err;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/rotate_test.c b/libtomcrypt/tests/rotate_test.c
new file mode 100644
index 0000000..f7c4610
--- /dev/null
+++ b/libtomcrypt/tests/rotate_test.c
@@ -0,0 +1,416 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+/* Test rotate macros */
+int rotate_test(void)
+{
+ ulong32 L32 = 0x12345678UL;
+ ulong64 L64 = CONST64(0x1122334455667788);
+ int err = 0;
+
+ /* ROR */
+ if (ROR(L32, 0 ) != 0x12345678UL) { fprintf(stderr, "ROR 0 failed\n"); err++; }
+ if (ROR(L32, 1 ) != 0x091a2b3cUL) { fprintf(stderr, "ROR 1 failed\n"); err++; }
+ if (ROR(L32, 2 ) != 0x048d159eUL) { fprintf(stderr, "ROR 2 failed\n"); err++; }
+ if (ROR(L32, 3 ) != 0x02468acfUL) { fprintf(stderr, "ROR 3 failed\n"); err++; }
+ if (ROR(L32, 4 ) != 0x81234567UL) { fprintf(stderr, "ROR 4 failed\n"); err++; }
+ if (ROR(L32, 5 ) != 0xc091a2b3UL) { fprintf(stderr, "ROR 5 failed\n"); err++; }
+ if (ROR(L32, 6 ) != 0xe048d159UL) { fprintf(stderr, "ROR 6 failed\n"); err++; }
+ if (ROR(L32, 7 ) != 0xf02468acUL) { fprintf(stderr, "ROR 7 failed\n"); err++; }
+ if (ROR(L32, 8 ) != 0x78123456UL) { fprintf(stderr, "ROR 8 failed\n"); err++; }
+ if (ROR(L32, 9 ) != 0x3c091a2bUL) { fprintf(stderr, "ROR 9 failed\n"); err++; }
+ if (ROR(L32, 10) != 0x9e048d15UL) { fprintf(stderr, "ROR 10 failed\n"); err++; }
+ if (ROR(L32, 11) != 0xcf02468aUL) { fprintf(stderr, "ROR 11 failed\n"); err++; }
+ if (ROR(L32, 12) != 0x67812345UL) { fprintf(stderr, "ROR 12 failed\n"); err++; }
+ if (ROR(L32, 13) != 0xb3c091a2UL) { fprintf(stderr, "ROR 13 failed\n"); err++; }
+ if (ROR(L32, 14) != 0x59e048d1UL) { fprintf(stderr, "ROR 14 failed\n"); err++; }
+ if (ROR(L32, 15) != 0xacf02468UL) { fprintf(stderr, "ROR 15 failed\n"); err++; }
+ if (ROR(L32, 16) != 0x56781234UL) { fprintf(stderr, "ROR 16 failed\n"); err++; }
+ if (ROR(L32, 17) != 0x2b3c091aUL) { fprintf(stderr, "ROR 17 failed\n"); err++; }
+ if (ROR(L32, 18) != 0x159e048dUL) { fprintf(stderr, "ROR 18 failed\n"); err++; }
+ if (ROR(L32, 19) != 0x8acf0246UL) { fprintf(stderr, "ROR 19 failed\n"); err++; }
+ if (ROR(L32, 20) != 0x45678123UL) { fprintf(stderr, "ROR 20 failed\n"); err++; }
+ if (ROR(L32, 21) != 0xa2b3c091UL) { fprintf(stderr, "ROR 21 failed\n"); err++; }
+ if (ROR(L32, 22) != 0xd159e048UL) { fprintf(stderr, "ROR 22 failed\n"); err++; }
+ if (ROR(L32, 23) != 0x68acf024UL) { fprintf(stderr, "ROR 23 failed\n"); err++; }
+ if (ROR(L32, 24) != 0x34567812UL) { fprintf(stderr, "ROR 24 failed\n"); err++; }
+ if (ROR(L32, 25) != 0x1a2b3c09UL) { fprintf(stderr, "ROR 25 failed\n"); err++; }
+ if (ROR(L32, 26) != 0x8d159e04UL) { fprintf(stderr, "ROR 26 failed\n"); err++; }
+ if (ROR(L32, 27) != 0x468acf02UL) { fprintf(stderr, "ROR 27 failed\n"); err++; }
+ if (ROR(L32, 28) != 0x23456781UL) { fprintf(stderr, "ROR 28 failed\n"); err++; }
+ if (ROR(L32, 29) != 0x91a2b3c0UL) { fprintf(stderr, "ROR 29 failed\n"); err++; }
+ if (ROR(L32, 30) != 0x48d159e0UL) { fprintf(stderr, "ROR 30 failed\n"); err++; }
+ if (ROR(L32, 31) != 0x2468acf0UL) { fprintf(stderr, "ROR 31 failed\n"); err++; }
+ /* ROR64 */
+ if (ROR64(L64, 0 ) != CONST64(0x1122334455667788)) { fprintf(stderr, "ROR64 0 failed\n"); err++; }
+ if (ROR64(L64, 1 ) != CONST64(0x089119a22ab33bc4)) { fprintf(stderr, "ROR64 1 failed\n"); err++; }
+ if (ROR64(L64, 2 ) != CONST64(0x04488cd115599de2)) { fprintf(stderr, "ROR64 2 failed\n"); err++; }
+ if (ROR64(L64, 3 ) != CONST64(0x022446688aaccef1)) { fprintf(stderr, "ROR64 3 failed\n"); err++; }
+ if (ROR64(L64, 4 ) != CONST64(0x8112233445566778)) { fprintf(stderr, "ROR64 4 failed\n"); err++; }
+ if (ROR64(L64, 5 ) != CONST64(0x4089119a22ab33bc)) { fprintf(stderr, "ROR64 5 failed\n"); err++; }
+ if (ROR64(L64, 6 ) != CONST64(0x204488cd115599de)) { fprintf(stderr, "ROR64 6 failed\n"); err++; }
+ if (ROR64(L64, 7 ) != CONST64(0x1022446688aaccef)) { fprintf(stderr, "ROR64 7 failed\n"); err++; }
+ if (ROR64(L64, 8 ) != CONST64(0x8811223344556677)) { fprintf(stderr, "ROR64 8 failed\n"); err++; }
+ if (ROR64(L64, 9 ) != CONST64(0xc4089119a22ab33b)) { fprintf(stderr, "ROR64 9 failed\n"); err++; }
+ if (ROR64(L64, 10) != CONST64(0xe204488cd115599d)) { fprintf(stderr, "ROR64 10 failed\n"); err++; }
+ if (ROR64(L64, 11) != CONST64(0xf1022446688aacce)) { fprintf(stderr, "ROR64 11 failed\n"); err++; }
+ if (ROR64(L64, 12) != CONST64(0x7881122334455667)) { fprintf(stderr, "ROR64 12 failed\n"); err++; }
+ if (ROR64(L64, 13) != CONST64(0xbc4089119a22ab33)) { fprintf(stderr, "ROR64 13 failed\n"); err++; }
+ if (ROR64(L64, 14) != CONST64(0xde204488cd115599)) { fprintf(stderr, "ROR64 14 failed\n"); err++; }
+ if (ROR64(L64, 15) != CONST64(0xef1022446688aacc)) { fprintf(stderr, "ROR64 15 failed\n"); err++; }
+ if (ROR64(L64, 16) != CONST64(0x7788112233445566)) { fprintf(stderr, "ROR64 16 failed\n"); err++; }
+ if (ROR64(L64, 17) != CONST64(0x3bc4089119a22ab3)) { fprintf(stderr, "ROR64 17 failed\n"); err++; }
+ if (ROR64(L64, 18) != CONST64(0x9de204488cd11559)) { fprintf(stderr, "ROR64 18 failed\n"); err++; }
+ if (ROR64(L64, 19) != CONST64(0xcef1022446688aac)) { fprintf(stderr, "ROR64 19 failed\n"); err++; }
+ if (ROR64(L64, 20) != CONST64(0x6778811223344556)) { fprintf(stderr, "ROR64 20 failed\n"); err++; }
+ if (ROR64(L64, 21) != CONST64(0x33bc4089119a22ab)) { fprintf(stderr, "ROR64 21 failed\n"); err++; }
+ if (ROR64(L64, 22) != CONST64(0x99de204488cd1155)) { fprintf(stderr, "ROR64 22 failed\n"); err++; }
+ if (ROR64(L64, 23) != CONST64(0xccef1022446688aa)) { fprintf(stderr, "ROR64 23 failed\n"); err++; }
+ if (ROR64(L64, 24) != CONST64(0x6677881122334455)) { fprintf(stderr, "ROR64 24 failed\n"); err++; }
+ if (ROR64(L64, 25) != CONST64(0xb33bc4089119a22a)) { fprintf(stderr, "ROR64 25 failed\n"); err++; }
+ if (ROR64(L64, 26) != CONST64(0x599de204488cd115)) { fprintf(stderr, "ROR64 26 failed\n"); err++; }
+ if (ROR64(L64, 27) != CONST64(0xaccef1022446688a)) { fprintf(stderr, "ROR64 27 failed\n"); err++; }
+ if (ROR64(L64, 28) != CONST64(0x5667788112233445)) { fprintf(stderr, "ROR64 28 failed\n"); err++; }
+ if (ROR64(L64, 29) != CONST64(0xab33bc4089119a22)) { fprintf(stderr, "ROR64 29 failed\n"); err++; }
+ if (ROR64(L64, 30) != CONST64(0x5599de204488cd11)) { fprintf(stderr, "ROR64 30 failed\n"); err++; }
+ if (ROR64(L64, 31) != CONST64(0xaaccef1022446688)) { fprintf(stderr, "ROR64 31 failed\n"); err++; }
+ if (ROR64(L64, 32) != CONST64(0x5566778811223344)) { fprintf(stderr, "ROR64 32 failed\n"); err++; }
+ if (ROR64(L64, 33) != CONST64(0x2ab33bc4089119a2)) { fprintf(stderr, "ROR64 33 failed\n"); err++; }
+ if (ROR64(L64, 34) != CONST64(0x15599de204488cd1)) { fprintf(stderr, "ROR64 34 failed\n"); err++; }
+ if (ROR64(L64, 35) != CONST64(0x8aaccef102244668)) { fprintf(stderr, "ROR64 35 failed\n"); err++; }
+ if (ROR64(L64, 36) != CONST64(0x4556677881122334)) { fprintf(stderr, "ROR64 36 failed\n"); err++; }
+ if (ROR64(L64, 37) != CONST64(0x22ab33bc4089119a)) { fprintf(stderr, "ROR64 37 failed\n"); err++; }
+ if (ROR64(L64, 38) != CONST64(0x115599de204488cd)) { fprintf(stderr, "ROR64 38 failed\n"); err++; }
+ if (ROR64(L64, 39) != CONST64(0x88aaccef10224466)) { fprintf(stderr, "ROR64 39 failed\n"); err++; }
+ if (ROR64(L64, 40) != CONST64(0x4455667788112233)) { fprintf(stderr, "ROR64 40 failed\n"); err++; }
+ if (ROR64(L64, 41) != CONST64(0xa22ab33bc4089119)) { fprintf(stderr, "ROR64 41 failed\n"); err++; }
+ if (ROR64(L64, 42) != CONST64(0xd115599de204488c)) { fprintf(stderr, "ROR64 42 failed\n"); err++; }
+ if (ROR64(L64, 43) != CONST64(0x688aaccef1022446)) { fprintf(stderr, "ROR64 43 failed\n"); err++; }
+ if (ROR64(L64, 44) != CONST64(0x3445566778811223)) { fprintf(stderr, "ROR64 44 failed\n"); err++; }
+ if (ROR64(L64, 45) != CONST64(0x9a22ab33bc408911)) { fprintf(stderr, "ROR64 45 failed\n"); err++; }
+ if (ROR64(L64, 46) != CONST64(0xcd115599de204488)) { fprintf(stderr, "ROR64 46 failed\n"); err++; }
+ if (ROR64(L64, 47) != CONST64(0x6688aaccef102244)) { fprintf(stderr, "ROR64 47 failed\n"); err++; }
+ if (ROR64(L64, 48) != CONST64(0x3344556677881122)) { fprintf(stderr, "ROR64 48 failed\n"); err++; }
+ if (ROR64(L64, 49) != CONST64(0x19a22ab33bc40891)) { fprintf(stderr, "ROR64 49 failed\n"); err++; }
+ if (ROR64(L64, 50) != CONST64(0x8cd115599de20448)) { fprintf(stderr, "ROR64 50 failed\n"); err++; }
+ if (ROR64(L64, 51) != CONST64(0x46688aaccef10224)) { fprintf(stderr, "ROR64 51 failed\n"); err++; }
+ if (ROR64(L64, 52) != CONST64(0x2334455667788112)) { fprintf(stderr, "ROR64 52 failed\n"); err++; }
+ if (ROR64(L64, 53) != CONST64(0x119a22ab33bc4089)) { fprintf(stderr, "ROR64 53 failed\n"); err++; }
+ if (ROR64(L64, 54) != CONST64(0x88cd115599de2044)) { fprintf(stderr, "ROR64 54 failed\n"); err++; }
+ if (ROR64(L64, 55) != CONST64(0x446688aaccef1022)) { fprintf(stderr, "ROR64 55 failed\n"); err++; }
+ if (ROR64(L64, 56) != CONST64(0x2233445566778811)) { fprintf(stderr, "ROR64 56 failed\n"); err++; }
+ if (ROR64(L64, 57) != CONST64(0x9119a22ab33bc408)) { fprintf(stderr, "ROR64 57 failed\n"); err++; }
+ if (ROR64(L64, 58) != CONST64(0x488cd115599de204)) { fprintf(stderr, "ROR64 58 failed\n"); err++; }
+ if (ROR64(L64, 59) != CONST64(0x2446688aaccef102)) { fprintf(stderr, "ROR64 59 failed\n"); err++; }
+ if (ROR64(L64, 60) != CONST64(0x1223344556677881)) { fprintf(stderr, "ROR64 60 failed\n"); err++; }
+ if (ROR64(L64, 61) != CONST64(0x89119a22ab33bc40)) { fprintf(stderr, "ROR64 61 failed\n"); err++; }
+ if (ROR64(L64, 62) != CONST64(0x4488cd115599de20)) { fprintf(stderr, "ROR64 62 failed\n"); err++; }
+ if (ROR64(L64, 63) != CONST64(0x22446688aaccef10)) { fprintf(stderr, "ROR64 63 failed\n"); err++; }
+ /* ROL */
+ if (ROL(L32, 0 ) != 0x12345678UL) { fprintf(stderr, "ROL 0 failed\n"); err++; }
+ if (ROL(L32, 1 ) != 0x2468acf0UL) { fprintf(stderr, "ROL 1 failed\n"); err++; }
+ if (ROL(L32, 2 ) != 0x48d159e0UL) { fprintf(stderr, "ROL 2 failed\n"); err++; }
+ if (ROL(L32, 3 ) != 0x91a2b3c0UL) { fprintf(stderr, "ROL 3 failed\n"); err++; }
+ if (ROL(L32, 4 ) != 0x23456781UL) { fprintf(stderr, "ROL 4 failed\n"); err++; }
+ if (ROL(L32, 5 ) != 0x468acf02UL) { fprintf(stderr, "ROL 5 failed\n"); err++; }
+ if (ROL(L32, 6 ) != 0x8d159e04UL) { fprintf(stderr, "ROL 6 failed\n"); err++; }
+ if (ROL(L32, 7 ) != 0x1a2b3c09UL) { fprintf(stderr, "ROL 7 failed\n"); err++; }
+ if (ROL(L32, 8 ) != 0x34567812UL) { fprintf(stderr, "ROL 8 failed\n"); err++; }
+ if (ROL(L32, 9 ) != 0x68acf024UL) { fprintf(stderr, "ROL 9 failed\n"); err++; }
+ if (ROL(L32, 10) != 0xd159e048UL) { fprintf(stderr, "ROL 10 failed\n"); err++; }
+ if (ROL(L32, 11) != 0xa2b3c091UL) { fprintf(stderr, "ROL 11 failed\n"); err++; }
+ if (ROL(L32, 12) != 0x45678123UL) { fprintf(stderr, "ROL 12 failed\n"); err++; }
+ if (ROL(L32, 13) != 0x8acf0246UL) { fprintf(stderr, "ROL 13 failed\n"); err++; }
+ if (ROL(L32, 14) != 0x159e048dUL) { fprintf(stderr, "ROL 14 failed\n"); err++; }
+ if (ROL(L32, 15) != 0x2b3c091aUL) { fprintf(stderr, "ROL 15 failed\n"); err++; }
+ if (ROL(L32, 16) != 0x56781234UL) { fprintf(stderr, "ROL 16 failed\n"); err++; }
+ if (ROL(L32, 17) != 0xacf02468UL) { fprintf(stderr, "ROL 17 failed\n"); err++; }
+ if (ROL(L32, 18) != 0x59e048d1UL) { fprintf(stderr, "ROL 18 failed\n"); err++; }
+ if (ROL(L32, 19) != 0xb3c091a2UL) { fprintf(stderr, "ROL 19 failed\n"); err++; }
+ if (ROL(L32, 20) != 0x67812345UL) { fprintf(stderr, "ROL 20 failed\n"); err++; }
+ if (ROL(L32, 21) != 0xcf02468aUL) { fprintf(stderr, "ROL 21 failed\n"); err++; }
+ if (ROL(L32, 22) != 0x9e048d15UL) { fprintf(stderr, "ROL 22 failed\n"); err++; }
+ if (ROL(L32, 23) != 0x3c091a2bUL) { fprintf(stderr, "ROL 23 failed\n"); err++; }
+ if (ROL(L32, 24) != 0x78123456UL) { fprintf(stderr, "ROL 24 failed\n"); err++; }
+ if (ROL(L32, 25) != 0xf02468acUL) { fprintf(stderr, "ROL 25 failed\n"); err++; }
+ if (ROL(L32, 26) != 0xe048d159UL) { fprintf(stderr, "ROL 26 failed\n"); err++; }
+ if (ROL(L32, 27) != 0xc091a2b3UL) { fprintf(stderr, "ROL 27 failed\n"); err++; }
+ if (ROL(L32, 28) != 0x81234567UL) { fprintf(stderr, "ROL 28 failed\n"); err++; }
+ if (ROL(L32, 29) != 0x02468acfUL) { fprintf(stderr, "ROL 29 failed\n"); err++; }
+ if (ROL(L32, 30) != 0x048d159eUL) { fprintf(stderr, "ROL 30 failed\n"); err++; }
+ if (ROL(L32, 31) != 0x091a2b3cUL) { fprintf(stderr, "ROL 31 failed\n"); err++; }
+ /* ROL64 */
+ if (ROL64(L64, 0 ) != CONST64(0x1122334455667788)) { fprintf(stderr, "ROL64 0 failed\n"); err++; }
+ if (ROL64(L64, 1 ) != CONST64(0x22446688aaccef10)) { fprintf(stderr, "ROL64 1 failed\n"); err++; }
+ if (ROL64(L64, 2 ) != CONST64(0x4488cd115599de20)) { fprintf(stderr, "ROL64 2 failed\n"); err++; }
+ if (ROL64(L64, 3 ) != CONST64(0x89119a22ab33bc40)) { fprintf(stderr, "ROL64 3 failed\n"); err++; }
+ if (ROL64(L64, 4 ) != CONST64(0x1223344556677881)) { fprintf(stderr, "ROL64 4 failed\n"); err++; }
+ if (ROL64(L64, 5 ) != CONST64(0x2446688aaccef102)) { fprintf(stderr, "ROL64 5 failed\n"); err++; }
+ if (ROL64(L64, 6 ) != CONST64(0x488cd115599de204)) { fprintf(stderr, "ROL64 6 failed\n"); err++; }
+ if (ROL64(L64, 7 ) != CONST64(0x9119a22ab33bc408)) { fprintf(stderr, "ROL64 7 failed\n"); err++; }
+ if (ROL64(L64, 8 ) != CONST64(0x2233445566778811)) { fprintf(stderr, "ROL64 8 failed\n"); err++; }
+ if (ROL64(L64, 9 ) != CONST64(0x446688aaccef1022)) { fprintf(stderr, "ROL64 9 failed\n"); err++; }
+ if (ROL64(L64, 10) != CONST64(0x88cd115599de2044)) { fprintf(stderr, "ROL64 10 failed\n"); err++; }
+ if (ROL64(L64, 11) != CONST64(0x119a22ab33bc4089)) { fprintf(stderr, "ROL64 11 failed\n"); err++; }
+ if (ROL64(L64, 12) != CONST64(0x2334455667788112)) { fprintf(stderr, "ROL64 12 failed\n"); err++; }
+ if (ROL64(L64, 13) != CONST64(0x46688aaccef10224)) { fprintf(stderr, "ROL64 13 failed\n"); err++; }
+ if (ROL64(L64, 14) != CONST64(0x8cd115599de20448)) { fprintf(stderr, "ROL64 14 failed\n"); err++; }
+ if (ROL64(L64, 15) != CONST64(0x19a22ab33bc40891)) { fprintf(stderr, "ROL64 15 failed\n"); err++; }
+ if (ROL64(L64, 16) != CONST64(0x3344556677881122)) { fprintf(stderr, "ROL64 16 failed\n"); err++; }
+ if (ROL64(L64, 17) != CONST64(0x6688aaccef102244)) { fprintf(stderr, "ROL64 17 failed\n"); err++; }
+ if (ROL64(L64, 18) != CONST64(0xcd115599de204488)) { fprintf(stderr, "ROL64 18 failed\n"); err++; }
+ if (ROL64(L64, 19) != CONST64(0x9a22ab33bc408911)) { fprintf(stderr, "ROL64 19 failed\n"); err++; }
+ if (ROL64(L64, 20) != CONST64(0x3445566778811223)) { fprintf(stderr, "ROL64 20 failed\n"); err++; }
+ if (ROL64(L64, 21) != CONST64(0x688aaccef1022446)) { fprintf(stderr, "ROL64 21 failed\n"); err++; }
+ if (ROL64(L64, 22) != CONST64(0xd115599de204488c)) { fprintf(stderr, "ROL64 22 failed\n"); err++; }
+ if (ROL64(L64, 23) != CONST64(0xa22ab33bc4089119)) { fprintf(stderr, "ROL64 23 failed\n"); err++; }
+ if (ROL64(L64, 24) != CONST64(0x4455667788112233)) { fprintf(stderr, "ROL64 24 failed\n"); err++; }
+ if (ROL64(L64, 25) != CONST64(0x88aaccef10224466)) { fprintf(stderr, "ROL64 25 failed\n"); err++; }
+ if (ROL64(L64, 26) != CONST64(0x115599de204488cd)) { fprintf(stderr, "ROL64 26 failed\n"); err++; }
+ if (ROL64(L64, 27) != CONST64(0x22ab33bc4089119a)) { fprintf(stderr, "ROL64 27 failed\n"); err++; }
+ if (ROL64(L64, 28) != CONST64(0x4556677881122334)) { fprintf(stderr, "ROL64 28 failed\n"); err++; }
+ if (ROL64(L64, 29) != CONST64(0x8aaccef102244668)) { fprintf(stderr, "ROL64 29 failed\n"); err++; }
+ if (ROL64(L64, 30) != CONST64(0x15599de204488cd1)) { fprintf(stderr, "ROL64 30 failed\n"); err++; }
+ if (ROL64(L64, 31) != CONST64(0x2ab33bc4089119a2)) { fprintf(stderr, "ROL64 31 failed\n"); err++; }
+ if (ROL64(L64, 32) != CONST64(0x5566778811223344)) { fprintf(stderr, "ROL64 32 failed\n"); err++; }
+ if (ROL64(L64, 33) != CONST64(0xaaccef1022446688)) { fprintf(stderr, "ROL64 33 failed\n"); err++; }
+ if (ROL64(L64, 34) != CONST64(0x5599de204488cd11)) { fprintf(stderr, "ROL64 34 failed\n"); err++; }
+ if (ROL64(L64, 35) != CONST64(0xab33bc4089119a22)) { fprintf(stderr, "ROL64 35 failed\n"); err++; }
+ if (ROL64(L64, 36) != CONST64(0x5667788112233445)) { fprintf(stderr, "ROL64 36 failed\n"); err++; }
+ if (ROL64(L64, 37) != CONST64(0xaccef1022446688a)) { fprintf(stderr, "ROL64 37 failed\n"); err++; }
+ if (ROL64(L64, 38) != CONST64(0x599de204488cd115)) { fprintf(stderr, "ROL64 38 failed\n"); err++; }
+ if (ROL64(L64, 39) != CONST64(0xb33bc4089119a22a)) { fprintf(stderr, "ROL64 39 failed\n"); err++; }
+ if (ROL64(L64, 40) != CONST64(0x6677881122334455)) { fprintf(stderr, "ROL64 40 failed\n"); err++; }
+ if (ROL64(L64, 41) != CONST64(0xccef1022446688aa)) { fprintf(stderr, "ROL64 41 failed\n"); err++; }
+ if (ROL64(L64, 42) != CONST64(0x99de204488cd1155)) { fprintf(stderr, "ROL64 42 failed\n"); err++; }
+ if (ROL64(L64, 43) != CONST64(0x33bc4089119a22ab)) { fprintf(stderr, "ROL64 43 failed\n"); err++; }
+ if (ROL64(L64, 44) != CONST64(0x6778811223344556)) { fprintf(stderr, "ROL64 44 failed\n"); err++; }
+ if (ROL64(L64, 45) != CONST64(0xcef1022446688aac)) { fprintf(stderr, "ROL64 45 failed\n"); err++; }
+ if (ROL64(L64, 46) != CONST64(0x9de204488cd11559)) { fprintf(stderr, "ROL64 46 failed\n"); err++; }
+ if (ROL64(L64, 47) != CONST64(0x3bc4089119a22ab3)) { fprintf(stderr, "ROL64 47 failed\n"); err++; }
+ if (ROL64(L64, 48) != CONST64(0x7788112233445566)) { fprintf(stderr, "ROL64 48 failed\n"); err++; }
+ if (ROL64(L64, 49) != CONST64(0xef1022446688aacc)) { fprintf(stderr, "ROL64 49 failed\n"); err++; }
+ if (ROL64(L64, 50) != CONST64(0xde204488cd115599)) { fprintf(stderr, "ROL64 50 failed\n"); err++; }
+ if (ROL64(L64, 51) != CONST64(0xbc4089119a22ab33)) { fprintf(stderr, "ROL64 51 failed\n"); err++; }
+ if (ROL64(L64, 52) != CONST64(0x7881122334455667)) { fprintf(stderr, "ROL64 52 failed\n"); err++; }
+ if (ROL64(L64, 53) != CONST64(0xf1022446688aacce)) { fprintf(stderr, "ROL64 53 failed\n"); err++; }
+ if (ROL64(L64, 54) != CONST64(0xe204488cd115599d)) { fprintf(stderr, "ROL64 54 failed\n"); err++; }
+ if (ROL64(L64, 55) != CONST64(0xc4089119a22ab33b)) { fprintf(stderr, "ROL64 55 failed\n"); err++; }
+ if (ROL64(L64, 56) != CONST64(0x8811223344556677)) { fprintf(stderr, "ROL64 56 failed\n"); err++; }
+ if (ROL64(L64, 57) != CONST64(0x1022446688aaccef)) { fprintf(stderr, "ROL64 57 failed\n"); err++; }
+ if (ROL64(L64, 58) != CONST64(0x204488cd115599de)) { fprintf(stderr, "ROL64 58 failed\n"); err++; }
+ if (ROL64(L64, 59) != CONST64(0x4089119a22ab33bc)) { fprintf(stderr, "ROL64 59 failed\n"); err++; }
+ if (ROL64(L64, 60) != CONST64(0x8112233445566778)) { fprintf(stderr, "ROL64 60 failed\n"); err++; }
+ if (ROL64(L64, 61) != CONST64(0x022446688aaccef1)) { fprintf(stderr, "ROL64 61 failed\n"); err++; }
+ if (ROL64(L64, 62) != CONST64(0x04488cd115599de2)) { fprintf(stderr, "ROL64 62 failed\n"); err++; }
+ if (ROL64(L64, 63) != CONST64(0x089119a22ab33bc4)) { fprintf(stderr, "ROL64 63 failed\n"); err++; }
+ /* RORc */
+ if (RORc(L32, 0 ) != 0x12345678UL) { fprintf(stderr, "RORc 0 failed\n"); err++; }
+ if (RORc(L32, 1 ) != 0x091a2b3cUL) { fprintf(stderr, "RORc 1 failed\n"); err++; }
+ if (RORc(L32, 2 ) != 0x048d159eUL) { fprintf(stderr, "RORc 2 failed\n"); err++; }
+ if (RORc(L32, 3 ) != 0x02468acfUL) { fprintf(stderr, "RORc 3 failed\n"); err++; }
+ if (RORc(L32, 4 ) != 0x81234567UL) { fprintf(stderr, "RORc 4 failed\n"); err++; }
+ if (RORc(L32, 5 ) != 0xc091a2b3UL) { fprintf(stderr, "RORc 5 failed\n"); err++; }
+ if (RORc(L32, 6 ) != 0xe048d159UL) { fprintf(stderr, "RORc 6 failed\n"); err++; }
+ if (RORc(L32, 7 ) != 0xf02468acUL) { fprintf(stderr, "RORc 7 failed\n"); err++; }
+ if (RORc(L32, 8 ) != 0x78123456UL) { fprintf(stderr, "RORc 8 failed\n"); err++; }
+ if (RORc(L32, 9 ) != 0x3c091a2bUL) { fprintf(stderr, "RORc 9 failed\n"); err++; }
+ if (RORc(L32, 10) != 0x9e048d15UL) { fprintf(stderr, "RORc 10 failed\n"); err++; }
+ if (RORc(L32, 11) != 0xcf02468aUL) { fprintf(stderr, "RORc 11 failed\n"); err++; }
+ if (RORc(L32, 12) != 0x67812345UL) { fprintf(stderr, "RORc 12 failed\n"); err++; }
+ if (RORc(L32, 13) != 0xb3c091a2UL) { fprintf(stderr, "RORc 13 failed\n"); err++; }
+ if (RORc(L32, 14) != 0x59e048d1UL) { fprintf(stderr, "RORc 14 failed\n"); err++; }
+ if (RORc(L32, 15) != 0xacf02468UL) { fprintf(stderr, "RORc 15 failed\n"); err++; }
+ if (RORc(L32, 16) != 0x56781234UL) { fprintf(stderr, "RORc 16 failed\n"); err++; }
+ if (RORc(L32, 17) != 0x2b3c091aUL) { fprintf(stderr, "RORc 17 failed\n"); err++; }
+ if (RORc(L32, 18) != 0x159e048dUL) { fprintf(stderr, "RORc 18 failed\n"); err++; }
+ if (RORc(L32, 19) != 0x8acf0246UL) { fprintf(stderr, "RORc 19 failed\n"); err++; }
+ if (RORc(L32, 20) != 0x45678123UL) { fprintf(stderr, "RORc 20 failed\n"); err++; }
+ if (RORc(L32, 21) != 0xa2b3c091UL) { fprintf(stderr, "RORc 21 failed\n"); err++; }
+ if (RORc(L32, 22) != 0xd159e048UL) { fprintf(stderr, "RORc 22 failed\n"); err++; }
+ if (RORc(L32, 23) != 0x68acf024UL) { fprintf(stderr, "RORc 23 failed\n"); err++; }
+ if (RORc(L32, 24) != 0x34567812UL) { fprintf(stderr, "RORc 24 failed\n"); err++; }
+ if (RORc(L32, 25) != 0x1a2b3c09UL) { fprintf(stderr, "RORc 25 failed\n"); err++; }
+ if (RORc(L32, 26) != 0x8d159e04UL) { fprintf(stderr, "RORc 26 failed\n"); err++; }
+ if (RORc(L32, 27) != 0x468acf02UL) { fprintf(stderr, "RORc 27 failed\n"); err++; }
+ if (RORc(L32, 28) != 0x23456781UL) { fprintf(stderr, "RORc 28 failed\n"); err++; }
+ if (RORc(L32, 29) != 0x91a2b3c0UL) { fprintf(stderr, "RORc 29 failed\n"); err++; }
+ if (RORc(L32, 30) != 0x48d159e0UL) { fprintf(stderr, "RORc 30 failed\n"); err++; }
+ if (RORc(L32, 31) != 0x2468acf0UL) { fprintf(stderr, "RORc 31 failed\n"); err++; }
+ /* ROR64c */
+ if (ROR64c(L64, 0 ) != CONST64(0x1122334455667788)) { fprintf(stderr, "ROR64c 0 failed\n"); err++; }
+ if (ROR64c(L64, 1 ) != CONST64(0x089119a22ab33bc4)) { fprintf(stderr, "ROR64c 1 failed\n"); err++; }
+ if (ROR64c(L64, 2 ) != CONST64(0x04488cd115599de2)) { fprintf(stderr, "ROR64c 2 failed\n"); err++; }
+ if (ROR64c(L64, 3 ) != CONST64(0x022446688aaccef1)) { fprintf(stderr, "ROR64c 3 failed\n"); err++; }
+ if (ROR64c(L64, 4 ) != CONST64(0x8112233445566778)) { fprintf(stderr, "ROR64c 4 failed\n"); err++; }
+ if (ROR64c(L64, 5 ) != CONST64(0x4089119a22ab33bc)) { fprintf(stderr, "ROR64c 5 failed\n"); err++; }
+ if (ROR64c(L64, 6 ) != CONST64(0x204488cd115599de)) { fprintf(stderr, "ROR64c 6 failed\n"); err++; }
+ if (ROR64c(L64, 7 ) != CONST64(0x1022446688aaccef)) { fprintf(stderr, "ROR64c 7 failed\n"); err++; }
+ if (ROR64c(L64, 8 ) != CONST64(0x8811223344556677)) { fprintf(stderr, "ROR64c 8 failed\n"); err++; }
+ if (ROR64c(L64, 9 ) != CONST64(0xc4089119a22ab33b)) { fprintf(stderr, "ROR64c 9 failed\n"); err++; }
+ if (ROR64c(L64, 10) != CONST64(0xe204488cd115599d)) { fprintf(stderr, "ROR64c 10 failed\n"); err++; }
+ if (ROR64c(L64, 11) != CONST64(0xf1022446688aacce)) { fprintf(stderr, "ROR64c 11 failed\n"); err++; }
+ if (ROR64c(L64, 12) != CONST64(0x7881122334455667)) { fprintf(stderr, "ROR64c 12 failed\n"); err++; }
+ if (ROR64c(L64, 13) != CONST64(0xbc4089119a22ab33)) { fprintf(stderr, "ROR64c 13 failed\n"); err++; }
+ if (ROR64c(L64, 14) != CONST64(0xde204488cd115599)) { fprintf(stderr, "ROR64c 14 failed\n"); err++; }
+ if (ROR64c(L64, 15) != CONST64(0xef1022446688aacc)) { fprintf(stderr, "ROR64c 15 failed\n"); err++; }
+ if (ROR64c(L64, 16) != CONST64(0x7788112233445566)) { fprintf(stderr, "ROR64c 16 failed\n"); err++; }
+ if (ROR64c(L64, 17) != CONST64(0x3bc4089119a22ab3)) { fprintf(stderr, "ROR64c 17 failed\n"); err++; }
+ if (ROR64c(L64, 18) != CONST64(0x9de204488cd11559)) { fprintf(stderr, "ROR64c 18 failed\n"); err++; }
+ if (ROR64c(L64, 19) != CONST64(0xcef1022446688aac)) { fprintf(stderr, "ROR64c 19 failed\n"); err++; }
+ if (ROR64c(L64, 20) != CONST64(0x6778811223344556)) { fprintf(stderr, "ROR64c 20 failed\n"); err++; }
+ if (ROR64c(L64, 21) != CONST64(0x33bc4089119a22ab)) { fprintf(stderr, "ROR64c 21 failed\n"); err++; }
+ if (ROR64c(L64, 22) != CONST64(0x99de204488cd1155)) { fprintf(stderr, "ROR64c 22 failed\n"); err++; }
+ if (ROR64c(L64, 23) != CONST64(0xccef1022446688aa)) { fprintf(stderr, "ROR64c 23 failed\n"); err++; }
+ if (ROR64c(L64, 24) != CONST64(0x6677881122334455)) { fprintf(stderr, "ROR64c 24 failed\n"); err++; }
+ if (ROR64c(L64, 25) != CONST64(0xb33bc4089119a22a)) { fprintf(stderr, "ROR64c 25 failed\n"); err++; }
+ if (ROR64c(L64, 26) != CONST64(0x599de204488cd115)) { fprintf(stderr, "ROR64c 26 failed\n"); err++; }
+ if (ROR64c(L64, 27) != CONST64(0xaccef1022446688a)) { fprintf(stderr, "ROR64c 27 failed\n"); err++; }
+ if (ROR64c(L64, 28) != CONST64(0x5667788112233445)) { fprintf(stderr, "ROR64c 28 failed\n"); err++; }
+ if (ROR64c(L64, 29) != CONST64(0xab33bc4089119a22)) { fprintf(stderr, "ROR64c 29 failed\n"); err++; }
+ if (ROR64c(L64, 30) != CONST64(0x5599de204488cd11)) { fprintf(stderr, "ROR64c 30 failed\n"); err++; }
+ if (ROR64c(L64, 31) != CONST64(0xaaccef1022446688)) { fprintf(stderr, "ROR64c 31 failed\n"); err++; }
+ if (ROR64c(L64, 32) != CONST64(0x5566778811223344)) { fprintf(stderr, "ROR64c 32 failed\n"); err++; }
+ if (ROR64c(L64, 33) != CONST64(0x2ab33bc4089119a2)) { fprintf(stderr, "ROR64c 33 failed\n"); err++; }
+ if (ROR64c(L64, 34) != CONST64(0x15599de204488cd1)) { fprintf(stderr, "ROR64c 34 failed\n"); err++; }
+ if (ROR64c(L64, 35) != CONST64(0x8aaccef102244668)) { fprintf(stderr, "ROR64c 35 failed\n"); err++; }
+ if (ROR64c(L64, 36) != CONST64(0x4556677881122334)) { fprintf(stderr, "ROR64c 36 failed\n"); err++; }
+ if (ROR64c(L64, 37) != CONST64(0x22ab33bc4089119a)) { fprintf(stderr, "ROR64c 37 failed\n"); err++; }
+ if (ROR64c(L64, 38) != CONST64(0x115599de204488cd)) { fprintf(stderr, "ROR64c 38 failed\n"); err++; }
+ if (ROR64c(L64, 39) != CONST64(0x88aaccef10224466)) { fprintf(stderr, "ROR64c 39 failed\n"); err++; }
+ if (ROR64c(L64, 40) != CONST64(0x4455667788112233)) { fprintf(stderr, "ROR64c 40 failed\n"); err++; }
+ if (ROR64c(L64, 41) != CONST64(0xa22ab33bc4089119)) { fprintf(stderr, "ROR64c 41 failed\n"); err++; }
+ if (ROR64c(L64, 42) != CONST64(0xd115599de204488c)) { fprintf(stderr, "ROR64c 42 failed\n"); err++; }
+ if (ROR64c(L64, 43) != CONST64(0x688aaccef1022446)) { fprintf(stderr, "ROR64c 43 failed\n"); err++; }
+ if (ROR64c(L64, 44) != CONST64(0x3445566778811223)) { fprintf(stderr, "ROR64c 44 failed\n"); err++; }
+ if (ROR64c(L64, 45) != CONST64(0x9a22ab33bc408911)) { fprintf(stderr, "ROR64c 45 failed\n"); err++; }
+ if (ROR64c(L64, 46) != CONST64(0xcd115599de204488)) { fprintf(stderr, "ROR64c 46 failed\n"); err++; }
+ if (ROR64c(L64, 47) != CONST64(0x6688aaccef102244)) { fprintf(stderr, "ROR64c 47 failed\n"); err++; }
+ if (ROR64c(L64, 48) != CONST64(0x3344556677881122)) { fprintf(stderr, "ROR64c 48 failed\n"); err++; }
+ if (ROR64c(L64, 49) != CONST64(0x19a22ab33bc40891)) { fprintf(stderr, "ROR64c 49 failed\n"); err++; }
+ if (ROR64c(L64, 50) != CONST64(0x8cd115599de20448)) { fprintf(stderr, "ROR64c 50 failed\n"); err++; }
+ if (ROR64c(L64, 51) != CONST64(0x46688aaccef10224)) { fprintf(stderr, "ROR64c 51 failed\n"); err++; }
+ if (ROR64c(L64, 52) != CONST64(0x2334455667788112)) { fprintf(stderr, "ROR64c 52 failed\n"); err++; }
+ if (ROR64c(L64, 53) != CONST64(0x119a22ab33bc4089)) { fprintf(stderr, "ROR64c 53 failed\n"); err++; }
+ if (ROR64c(L64, 54) != CONST64(0x88cd115599de2044)) { fprintf(stderr, "ROR64c 54 failed\n"); err++; }
+ if (ROR64c(L64, 55) != CONST64(0x446688aaccef1022)) { fprintf(stderr, "ROR64c 55 failed\n"); err++; }
+ if (ROR64c(L64, 56) != CONST64(0x2233445566778811)) { fprintf(stderr, "ROR64c 56 failed\n"); err++; }
+ if (ROR64c(L64, 57) != CONST64(0x9119a22ab33bc408)) { fprintf(stderr, "ROR64c 57 failed\n"); err++; }
+ if (ROR64c(L64, 58) != CONST64(0x488cd115599de204)) { fprintf(stderr, "ROR64c 58 failed\n"); err++; }
+ if (ROR64c(L64, 59) != CONST64(0x2446688aaccef102)) { fprintf(stderr, "ROR64c 59 failed\n"); err++; }
+ if (ROR64c(L64, 60) != CONST64(0x1223344556677881)) { fprintf(stderr, "ROR64c 60 failed\n"); err++; }
+ if (ROR64c(L64, 61) != CONST64(0x89119a22ab33bc40)) { fprintf(stderr, "ROR64c 61 failed\n"); err++; }
+ if (ROR64c(L64, 62) != CONST64(0x4488cd115599de20)) { fprintf(stderr, "ROR64c 62 failed\n"); err++; }
+ if (ROR64c(L64, 63) != CONST64(0x22446688aaccef10)) { fprintf(stderr, "ROR64c 63 failed\n"); err++; }
+ /* ROLc */
+ if (ROLc(L32, 0 ) != 0x12345678UL) { fprintf(stderr, "ROLc 0 failed\n"); err++; }
+ if (ROLc(L32, 1 ) != 0x2468acf0UL) { fprintf(stderr, "ROLc 1 failed\n"); err++; }
+ if (ROLc(L32, 2 ) != 0x48d159e0UL) { fprintf(stderr, "ROLc 2 failed\n"); err++; }
+ if (ROLc(L32, 3 ) != 0x91a2b3c0UL) { fprintf(stderr, "ROLc 3 failed\n"); err++; }
+ if (ROLc(L32, 4 ) != 0x23456781UL) { fprintf(stderr, "ROLc 4 failed\n"); err++; }
+ if (ROLc(L32, 5 ) != 0x468acf02UL) { fprintf(stderr, "ROLc 5 failed\n"); err++; }
+ if (ROLc(L32, 6 ) != 0x8d159e04UL) { fprintf(stderr, "ROLc 6 failed\n"); err++; }
+ if (ROLc(L32, 7 ) != 0x1a2b3c09UL) { fprintf(stderr, "ROLc 7 failed\n"); err++; }
+ if (ROLc(L32, 8 ) != 0x34567812UL) { fprintf(stderr, "ROLc 8 failed\n"); err++; }
+ if (ROLc(L32, 9 ) != 0x68acf024UL) { fprintf(stderr, "ROLc 9 failed\n"); err++; }
+ if (ROLc(L32, 10) != 0xd159e048UL) { fprintf(stderr, "ROLc 10 failed\n"); err++; }
+ if (ROLc(L32, 11) != 0xa2b3c091UL) { fprintf(stderr, "ROLc 11 failed\n"); err++; }
+ if (ROLc(L32, 12) != 0x45678123UL) { fprintf(stderr, "ROLc 12 failed\n"); err++; }
+ if (ROLc(L32, 13) != 0x8acf0246UL) { fprintf(stderr, "ROLc 13 failed\n"); err++; }
+ if (ROLc(L32, 14) != 0x159e048dUL) { fprintf(stderr, "ROLc 14 failed\n"); err++; }
+ if (ROLc(L32, 15) != 0x2b3c091aUL) { fprintf(stderr, "ROLc 15 failed\n"); err++; }
+ if (ROLc(L32, 16) != 0x56781234UL) { fprintf(stderr, "ROLc 16 failed\n"); err++; }
+ if (ROLc(L32, 17) != 0xacf02468UL) { fprintf(stderr, "ROLc 17 failed\n"); err++; }
+ if (ROLc(L32, 18) != 0x59e048d1UL) { fprintf(stderr, "ROLc 18 failed\n"); err++; }
+ if (ROLc(L32, 19) != 0xb3c091a2UL) { fprintf(stderr, "ROLc 19 failed\n"); err++; }
+ if (ROLc(L32, 20) != 0x67812345UL) { fprintf(stderr, "ROLc 20 failed\n"); err++; }
+ if (ROLc(L32, 21) != 0xcf02468aUL) { fprintf(stderr, "ROLc 21 failed\n"); err++; }
+ if (ROLc(L32, 22) != 0x9e048d15UL) { fprintf(stderr, "ROLc 22 failed\n"); err++; }
+ if (ROLc(L32, 23) != 0x3c091a2bUL) { fprintf(stderr, "ROLc 23 failed\n"); err++; }
+ if (ROLc(L32, 24) != 0x78123456UL) { fprintf(stderr, "ROLc 24 failed\n"); err++; }
+ if (ROLc(L32, 25) != 0xf02468acUL) { fprintf(stderr, "ROLc 25 failed\n"); err++; }
+ if (ROLc(L32, 26) != 0xe048d159UL) { fprintf(stderr, "ROLc 26 failed\n"); err++; }
+ if (ROLc(L32, 27) != 0xc091a2b3UL) { fprintf(stderr, "ROLc 27 failed\n"); err++; }
+ if (ROLc(L32, 28) != 0x81234567UL) { fprintf(stderr, "ROLc 28 failed\n"); err++; }
+ if (ROLc(L32, 29) != 0x02468acfUL) { fprintf(stderr, "ROLc 29 failed\n"); err++; }
+ if (ROLc(L32, 30) != 0x048d159eUL) { fprintf(stderr, "ROLc 30 failed\n"); err++; }
+ if (ROLc(L32, 31) != 0x091a2b3cUL) { fprintf(stderr, "ROLc 31 failed\n"); err++; }
+ /* ROL64c */
+ if (ROL64c(L64, 0 ) != CONST64(0x1122334455667788)) { fprintf(stderr, "ROL64c 0 failed\n"); err++; }
+ if (ROL64c(L64, 1 ) != CONST64(0x22446688aaccef10)) { fprintf(stderr, "ROL64c 1 failed\n"); err++; }
+ if (ROL64c(L64, 2 ) != CONST64(0x4488cd115599de20)) { fprintf(stderr, "ROL64c 2 failed\n"); err++; }
+ if (ROL64c(L64, 3 ) != CONST64(0x89119a22ab33bc40)) { fprintf(stderr, "ROL64c 3 failed\n"); err++; }
+ if (ROL64c(L64, 4 ) != CONST64(0x1223344556677881)) { fprintf(stderr, "ROL64c 4 failed\n"); err++; }
+ if (ROL64c(L64, 5 ) != CONST64(0x2446688aaccef102)) { fprintf(stderr, "ROL64c 5 failed\n"); err++; }
+ if (ROL64c(L64, 6 ) != CONST64(0x488cd115599de204)) { fprintf(stderr, "ROL64c 6 failed\n"); err++; }
+ if (ROL64c(L64, 7 ) != CONST64(0x9119a22ab33bc408)) { fprintf(stderr, "ROL64c 7 failed\n"); err++; }
+ if (ROL64c(L64, 8 ) != CONST64(0x2233445566778811)) { fprintf(stderr, "ROL64c 8 failed\n"); err++; }
+ if (ROL64c(L64, 9 ) != CONST64(0x446688aaccef1022)) { fprintf(stderr, "ROL64c 9 failed\n"); err++; }
+ if (ROL64c(L64, 10) != CONST64(0x88cd115599de2044)) { fprintf(stderr, "ROL64c 10 failed\n"); err++; }
+ if (ROL64c(L64, 11) != CONST64(0x119a22ab33bc4089)) { fprintf(stderr, "ROL64c 11 failed\n"); err++; }
+ if (ROL64c(L64, 12) != CONST64(0x2334455667788112)) { fprintf(stderr, "ROL64c 12 failed\n"); err++; }
+ if (ROL64c(L64, 13) != CONST64(0x46688aaccef10224)) { fprintf(stderr, "ROL64c 13 failed\n"); err++; }
+ if (ROL64c(L64, 14) != CONST64(0x8cd115599de20448)) { fprintf(stderr, "ROL64c 14 failed\n"); err++; }
+ if (ROL64c(L64, 15) != CONST64(0x19a22ab33bc40891)) { fprintf(stderr, "ROL64c 15 failed\n"); err++; }
+ if (ROL64c(L64, 16) != CONST64(0x3344556677881122)) { fprintf(stderr, "ROL64c 16 failed\n"); err++; }
+ if (ROL64c(L64, 17) != CONST64(0x6688aaccef102244)) { fprintf(stderr, "ROL64c 17 failed\n"); err++; }
+ if (ROL64c(L64, 18) != CONST64(0xcd115599de204488)) { fprintf(stderr, "ROL64c 18 failed\n"); err++; }
+ if (ROL64c(L64, 19) != CONST64(0x9a22ab33bc408911)) { fprintf(stderr, "ROL64c 19 failed\n"); err++; }
+ if (ROL64c(L64, 20) != CONST64(0x3445566778811223)) { fprintf(stderr, "ROL64c 20 failed\n"); err++; }
+ if (ROL64c(L64, 21) != CONST64(0x688aaccef1022446)) { fprintf(stderr, "ROL64c 21 failed\n"); err++; }
+ if (ROL64c(L64, 22) != CONST64(0xd115599de204488c)) { fprintf(stderr, "ROL64c 22 failed\n"); err++; }
+ if (ROL64c(L64, 23) != CONST64(0xa22ab33bc4089119)) { fprintf(stderr, "ROL64c 23 failed\n"); err++; }
+ if (ROL64c(L64, 24) != CONST64(0x4455667788112233)) { fprintf(stderr, "ROL64c 24 failed\n"); err++; }
+ if (ROL64c(L64, 25) != CONST64(0x88aaccef10224466)) { fprintf(stderr, "ROL64c 25 failed\n"); err++; }
+ if (ROL64c(L64, 26) != CONST64(0x115599de204488cd)) { fprintf(stderr, "ROL64c 26 failed\n"); err++; }
+ if (ROL64c(L64, 27) != CONST64(0x22ab33bc4089119a)) { fprintf(stderr, "ROL64c 27 failed\n"); err++; }
+ if (ROL64c(L64, 28) != CONST64(0x4556677881122334)) { fprintf(stderr, "ROL64c 28 failed\n"); err++; }
+ if (ROL64c(L64, 29) != CONST64(0x8aaccef102244668)) { fprintf(stderr, "ROL64c 29 failed\n"); err++; }
+ if (ROL64c(L64, 30) != CONST64(0x15599de204488cd1)) { fprintf(stderr, "ROL64c 30 failed\n"); err++; }
+ if (ROL64c(L64, 31) != CONST64(0x2ab33bc4089119a2)) { fprintf(stderr, "ROL64c 31 failed\n"); err++; }
+ if (ROL64c(L64, 32) != CONST64(0x5566778811223344)) { fprintf(stderr, "ROL64c 32 failed\n"); err++; }
+ if (ROL64c(L64, 33) != CONST64(0xaaccef1022446688)) { fprintf(stderr, "ROL64c 33 failed\n"); err++; }
+ if (ROL64c(L64, 34) != CONST64(0x5599de204488cd11)) { fprintf(stderr, "ROL64c 34 failed\n"); err++; }
+ if (ROL64c(L64, 35) != CONST64(0xab33bc4089119a22)) { fprintf(stderr, "ROL64c 35 failed\n"); err++; }
+ if (ROL64c(L64, 36) != CONST64(0x5667788112233445)) { fprintf(stderr, "ROL64c 36 failed\n"); err++; }
+ if (ROL64c(L64, 37) != CONST64(0xaccef1022446688a)) { fprintf(stderr, "ROL64c 37 failed\n"); err++; }
+ if (ROL64c(L64, 38) != CONST64(0x599de204488cd115)) { fprintf(stderr, "ROL64c 38 failed\n"); err++; }
+ if (ROL64c(L64, 39) != CONST64(0xb33bc4089119a22a)) { fprintf(stderr, "ROL64c 39 failed\n"); err++; }
+ if (ROL64c(L64, 40) != CONST64(0x6677881122334455)) { fprintf(stderr, "ROL64c 40 failed\n"); err++; }
+ if (ROL64c(L64, 41) != CONST64(0xccef1022446688aa)) { fprintf(stderr, "ROL64c 41 failed\n"); err++; }
+ if (ROL64c(L64, 42) != CONST64(0x99de204488cd1155)) { fprintf(stderr, "ROL64c 42 failed\n"); err++; }
+ if (ROL64c(L64, 43) != CONST64(0x33bc4089119a22ab)) { fprintf(stderr, "ROL64c 43 failed\n"); err++; }
+ if (ROL64c(L64, 44) != CONST64(0x6778811223344556)) { fprintf(stderr, "ROL64c 44 failed\n"); err++; }
+ if (ROL64c(L64, 45) != CONST64(0xcef1022446688aac)) { fprintf(stderr, "ROL64c 45 failed\n"); err++; }
+ if (ROL64c(L64, 46) != CONST64(0x9de204488cd11559)) { fprintf(stderr, "ROL64c 46 failed\n"); err++; }
+ if (ROL64c(L64, 47) != CONST64(0x3bc4089119a22ab3)) { fprintf(stderr, "ROL64c 47 failed\n"); err++; }
+ if (ROL64c(L64, 48) != CONST64(0x7788112233445566)) { fprintf(stderr, "ROL64c 48 failed\n"); err++; }
+ if (ROL64c(L64, 49) != CONST64(0xef1022446688aacc)) { fprintf(stderr, "ROL64c 49 failed\n"); err++; }
+ if (ROL64c(L64, 50) != CONST64(0xde204488cd115599)) { fprintf(stderr, "ROL64c 50 failed\n"); err++; }
+ if (ROL64c(L64, 51) != CONST64(0xbc4089119a22ab33)) { fprintf(stderr, "ROL64c 51 failed\n"); err++; }
+ if (ROL64c(L64, 52) != CONST64(0x7881122334455667)) { fprintf(stderr, "ROL64c 52 failed\n"); err++; }
+ if (ROL64c(L64, 53) != CONST64(0xf1022446688aacce)) { fprintf(stderr, "ROL64c 53 failed\n"); err++; }
+ if (ROL64c(L64, 54) != CONST64(0xe204488cd115599d)) { fprintf(stderr, "ROL64c 54 failed\n"); err++; }
+ if (ROL64c(L64, 55) != CONST64(0xc4089119a22ab33b)) { fprintf(stderr, "ROL64c 55 failed\n"); err++; }
+ if (ROL64c(L64, 56) != CONST64(0x8811223344556677)) { fprintf(stderr, "ROL64c 56 failed\n"); err++; }
+ if (ROL64c(L64, 57) != CONST64(0x1022446688aaccef)) { fprintf(stderr, "ROL64c 57 failed\n"); err++; }
+ if (ROL64c(L64, 58) != CONST64(0x204488cd115599de)) { fprintf(stderr, "ROL64c 58 failed\n"); err++; }
+ if (ROL64c(L64, 59) != CONST64(0x4089119a22ab33bc)) { fprintf(stderr, "ROL64c 59 failed\n"); err++; }
+ if (ROL64c(L64, 60) != CONST64(0x8112233445566778)) { fprintf(stderr, "ROL64c 60 failed\n"); err++; }
+ if (ROL64c(L64, 61) != CONST64(0x022446688aaccef1)) { fprintf(stderr, "ROL64c 61 failed\n"); err++; }
+ if (ROL64c(L64, 62) != CONST64(0x04488cd115599de2)) { fprintf(stderr, "ROL64c 62 failed\n"); err++; }
+ if (ROL64c(L64, 63) != CONST64(0x089119a22ab33bc4)) { fprintf(stderr, "ROL64c 63 failed\n"); err++; }
+
+ return err;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/rsa_test.c b/libtomcrypt/tests/rsa_test.c
new file mode 100644
index 0000000..44fa1d0
--- /dev/null
+++ b/libtomcrypt/tests/rsa_test.c
@@ -0,0 +1,702 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#if defined(LTC_MRSA) && defined(LTC_TEST_MPI)
+
+#define RSA_MSGSIZE 78
+
+/* These are test keys [see file test.key] that I use to test my import/export against */
+static const unsigned char openssl_private_rsa[] = {
+ 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a,
+ 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7,
+ 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5,
+ 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a,
+ 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12,
+ 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61,
+ 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76,
+ 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f,
+ 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0x02, 0x81, 0x81, 0x00, 0xc8, 0x62, 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97,
+ 0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a, 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65,
+ 0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6, 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28,
+ 0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f, 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d,
+ 0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac, 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad,
+ 0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4, 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8,
+ 0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95, 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c,
+ 0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b, 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b,
+ 0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41, 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b,
+ 0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb, 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a,
+ 0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f, 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42,
+ 0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05, 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b,
+ 0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc, 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b,
+ 0x04, 0x08, 0x84, 0x21, 0x60, 0xf0, 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e,
+ 0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c, 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a,
+ 0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed, 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc,
+ 0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8, 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d,
+ 0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31, 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf,
+ 0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27, 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a,
+ 0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63, 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23,
+ 0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8, 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab,
+ 0x90, 0x88, 0xfa, 0x60, 0x08, 0x29, 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe,
+ 0x97, 0x64, 0x63, 0x71, 0x74, 0x22, 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54,
+ 0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6, 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35,
+ 0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c, 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02,
+ 0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8, 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60,
+ 0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7, 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c,
+ 0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39, 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f,
+ 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17,
+ 0x4a, 0x9f, };
+
+static const unsigned char x509_public_rsa[] =
+ "MIICdTCCAd4CCQCYjCwz0l9JpjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJD\
+ WjEPMA0GA1UECAwGTW9yYXZhMQ0wCwYDVQQHDARCcm5vMRAwDgYDVQQKDAdMVEMg\
+ THRkMQ8wDQYDVQQLDAZDcnlwdG8xEjAQBgNVBAMMCVRlc3QgQ2VydDEYMBYGCSqG\
+ SIb3DQEJARYJdGVzdEBjZXJ0MCAXDTE3MDMwOTIzNDMzOVoYDzIyOTAxMjIyMjM0\
+ MzM5WjB+MQswCQYDVQQGEwJDWjEPMA0GA1UECAwGTW9yYXZhMQ0wCwYDVQQHDARC\
+ cm5vMRAwDgYDVQQKDAdMVEMgTHRkMQ8wDQYDVQQLDAZDcnlwdG8xEjAQBgNVBAMM\
+ CVRlc3QgQ2VydDEYMBYGCSqGSIb3DQEJARYJdGVzdEBjZXJ0MIGfMA0GCSqGSIb3\
+ DQEBAQUAA4GNADCBiQKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97b\
+ fYUtlmXlP3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7k\
+ EY5BaHxhE9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE\
+ /QIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAApwWqupmmLGHeKOLFLcthQpAXXYep6T\
+ 3S3e8X7fIG6TGhfvn5DHn+/V/C4184oOCwImI+VYRokdXdQ1AMGfVUomHJxsFPia\
+ bv5Aw3hiKsIG3jigKHwmMScgkl3yn+8hLkx6thNbqQoa6Yyo20RqaEFBwlZ5G8lF\
+ rZsdeO84SeCH";
+
+static const unsigned char pkcs8_private_rsa[] = {
+ 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01,
+ 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7,
+ 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84,
+ 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28,
+ 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b,
+ 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc,
+ 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe,
+ 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58,
+ 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31,
+ 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0xc8, 0x62,
+ 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97, 0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a,
+ 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65, 0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6,
+ 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28, 0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f,
+ 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d, 0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac,
+ 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad, 0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4,
+ 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8, 0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95,
+ 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c, 0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b,
+ 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b, 0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41,
+ 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b, 0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb,
+ 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a, 0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f,
+ 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42, 0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05,
+ 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b, 0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc,
+ 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b, 0x04, 0x08, 0x84, 0x21, 0x60, 0xf0,
+ 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e, 0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c,
+ 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a, 0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed,
+ 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc, 0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8,
+ 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d, 0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31,
+ 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf, 0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27,
+ 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a, 0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63,
+ 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23, 0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8,
+ 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab, 0x90, 0x88, 0xfa, 0x60, 0x08, 0x29,
+ 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe, 0x97, 0x64, 0x63, 0x71, 0x74, 0x22,
+ 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54, 0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6,
+ 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35, 0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c,
+ 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02, 0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8,
+ 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60, 0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7,
+ 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c, 0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39,
+ 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f, 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e,
+ 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, 0x4a, 0x9f };
+
+/* private key - hexadecimal */
+enum {
+ pk_d ,
+ pk_dP,
+ pk_dQ,
+ pk_e ,
+ pk_N ,
+ pk_p ,
+ pk_q ,
+ pk_qP,
+};
+static const char *hex_key[] = {
+ "C862B9EADE44531D5697D9979E1ACF301E0A8845862930A34D9F616573E0D6878FB6F306A382DC7CACFE9B289AAEFDFBFE2F0ED89704E3BB1FD1EC0DBAA3497F47AC8A44047E86B739423FAD1EB70EA551F440631EFDBDEA9F419FA8901D6F0A5A9513110D80AF5F64988A2C786865B02B8BA25387CAF16404ABF27BDB83C881",
+ "6DEBC32D2EF05EA488310529008AD195299B83CF75DB31E37A27DE3A74300C764CD4502A402D39D99963A95D80AE53CA943F05231EF80504E1B835F217B3A089",
+ "AB9088FA600829509A438BA050CCD85AFE976463717422A320025ACFEBC6169554D1CBAB8D1AC600FA08929C71D552523596714B8B920CD0E9BFAD630BA5E9B1",
+ "010001",
+ "CF9ADE648ADAC83320A9D783311954B29A85A7A1B77533B6A9AC8424B3DEDB7D852D9665E53F7295249F2868CA4FDB441C3E60128ADD26A5EBFF0B5ED48838492A6E5BBF123747BD056BBCDBF3EEE4118E41687C6113D742C880BE368FDC088B4FACA4E2760CC9636C495893EDCCAADC253B0A603F8B543AC34D31E794A444FD",
+ "F7BE5E23C3323FBF8B8E3AEEFCFCCBE5F7F10BBC4282AED57A3ECAF7D5693F6425A21FB77575059242EBB8F1F30A05E394D1557835A036A09B7C92846CDDDC4D",
+ "D6860E85420B0408842160F00E0D88FD1E3610654F1E53B40872805C3F596617E698F2E96C7A064CAC763DED8CA1CEAD1BBDB47D28BCE30E388D99D805B5A371",
+ "DCCC27C8E4DC6248D59BAFF5AB60F621FD53E2B75D09C91AA104A9FC612C5D04583A5A39F14A215667FDCC20A38F78185A793D2E8E7E860AE6A833C104174A9F" };
+
+/*** openssl public RSA key in DER format */
+static const unsigned char openssl_public_rsa[] = {
+ 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde,
+ 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7,
+ 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96,
+ 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60,
+ 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b,
+ 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68,
+ 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4,
+ 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a,
+ 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01,
+ 0x00, 0x01, };
+
+/* same key but with extra headers stripped */
+static const unsigned char openssl_public_rsa_stripped[] = {
+ 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde,
+ 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7,
+ 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96,
+ 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60,
+ 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b,
+ 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68,
+ 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4,
+ 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a,
+ 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01,
+ 0x00, 0x01, };
+
+
+/* generated with the private key above as:
+ echo -n 'test' | openssl rsautl -sign -inkey rsa_private.pem -pkcs -hexdump
+ */
+static const unsigned char openssl_rsautl_pkcs[] = {
+ 0x24, 0xef, 0x54, 0xea, 0x1a, 0x12, 0x0c, 0xf4, 0x04, 0x0c, 0x48, 0xc8, 0xe8, 0x17, 0xd2, 0x6f,
+ 0xc3, 0x41, 0xb3, 0x97, 0x5c, 0xbc, 0xa3, 0x2d, 0x21, 0x00, 0x10, 0x0e, 0xbb, 0xf7, 0x30, 0x21,
+ 0x7e, 0x12, 0xd2, 0xdf, 0x26, 0x28, 0xd8, 0x0f, 0x6d, 0x4d, 0xc8, 0x4d, 0xa8, 0x78, 0xe7, 0x03,
+ 0xee, 0xbc, 0x68, 0xba, 0x98, 0xea, 0xe9, 0xb6, 0x06, 0x8d, 0x85, 0x5b, 0xdb, 0xa6, 0x49, 0x86,
+ 0x6f, 0xc7, 0x3d, 0xe0, 0x53, 0x83, 0xe0, 0xea, 0xb1, 0x08, 0x6a, 0x7b, 0xbd, 0xeb, 0xb5, 0x4a,
+ 0xdd, 0xbc, 0x64, 0x97, 0x8c, 0x17, 0x20, 0xa3, 0x5c, 0xd4, 0xb8, 0x87, 0x43, 0xc5, 0x13, 0xad,
+ 0x41, 0x6e, 0x45, 0x41, 0x32, 0xd4, 0x09, 0x12, 0x7f, 0xdc, 0x59, 0x1f, 0x28, 0x3f, 0x1e, 0xbc,
+ 0xef, 0x57, 0x23, 0x4b, 0x3a, 0xa3, 0x24, 0x91, 0x4d, 0xfb, 0xb2, 0xd4, 0xe7, 0x5e, 0x41, 0x7e,
+};
+
+extern const unsigned char _der_tests_cacert_root_cert[];
+extern const unsigned long _der_tests_cacert_root_cert_size;
+
+static int rsa_compat_test(void)
+{
+ rsa_key key, pubkey;
+ int stat, i;
+ unsigned char buf[1024], key_parts[8][128];
+ unsigned long len, key_lens[8];
+
+ /* try reading the key */
+ DO(rsa_import(openssl_private_rsa, sizeof(openssl_private_rsa), &key));
+ DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &pubkey));
+
+ /* sign-verify a message with PKCS #1 v1.5 no ASN.1 */
+ len = sizeof(buf);
+ DO(rsa_sign_hash_ex((unsigned char*)"test", 4, buf, &len, LTC_PKCS_1_V1_5_NA1, NULL, 0, 0, 0, &key));
+ if (len != sizeof(openssl_rsautl_pkcs) || memcmp(buf, openssl_rsautl_pkcs, len)) {
+ fprintf(stderr, "RSA rsa_sign_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n");
+ return 1;
+ }
+ stat = 0;
+ DO(rsa_verify_hash_ex(openssl_rsautl_pkcs, sizeof(openssl_rsautl_pkcs), (unsigned char*)"test", 4, LTC_PKCS_1_V1_5_NA1, 0, 0, &stat, &pubkey));
+ if (stat != 1) {
+ fprintf(stderr, "RSA rsa_verify_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n");
+ return 1;
+ }
+ rsa_free(&pubkey);
+
+ /* now try to export private/public and compare */
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+ if (compare_testvector(buf, len, openssl_private_rsa, sizeof(openssl_private_rsa), "RSA private export (from OpenSSL)", 0)) {
+ return 1;
+ }
+
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+ if (compare_testvector(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from OpenSSL private key)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* try reading the public key */
+ DO(rsa_import(openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+ if (compare_testvector(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from stripped OpenSSL)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* try reading the public key */
+ DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+ if (compare_testvector(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from OpenSSL)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* try import private key in pkcs8 format */
+ DO(rsa_import_pkcs8(pkcs8_private_rsa, sizeof(pkcs8_private_rsa), NULL, 0, &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+ if (compare_testvector(buf, len, openssl_private_rsa, sizeof(openssl_private_rsa), "RSA private export (from PKCS#8)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* convert raw hexadecimal numbers to binary */
+ for (i = 0; i < 8; ++i) {
+ key_lens[i] = sizeof(key_parts[i]);
+ DO(radix_to_bin(hex_key[i], 16, key_parts[i], &key_lens[i]));
+ }
+ /* try import private key from converted raw hexadecimal numbers */
+ DO(rsa_set_key(key_parts[pk_N], key_lens[pk_N], key_parts[pk_e], key_lens[pk_e], key_parts[pk_d], key_lens[pk_d], &key));
+ DO(rsa_set_factors(key_parts[pk_p], key_lens[pk_p], key_parts[pk_q], key_lens[pk_q], &key));
+ DO(rsa_set_crt_params(key_parts[pk_dP], key_lens[pk_dP], key_parts[pk_dQ], key_lens[pk_dQ], key_parts[pk_qP], key_lens[pk_qP], &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+ if (compare_testvector(buf, len, openssl_private_rsa, sizeof(openssl_private_rsa), "RSA private export (from hex)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* try import public key from converted raw hexadecimal numbers */
+ DO(rsa_set_key(key_parts[pk_N], key_lens[pk_N], key_parts[pk_e], key_lens[pk_e], NULL, 0, &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+ if (compare_testvector(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from hex)", 0)) {
+ return 1;
+ }
+ rsa_free(&key);
+
+ /* try export in SubjectPublicKeyInfo format of the public key */
+ DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key));
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
+ if (len != sizeof(openssl_public_rsa) || memcmp(buf, openssl_public_rsa, len)) {
+ fprintf(stderr, "RSA(public) SSL public X.509 export failed to match OpenSSL output\n");
+ print_hex("should", openssl_public_rsa, sizeof(openssl_public_rsa));
+ print_hex("is", buf, len);
+ return 1;
+ }
+ rsa_free(&key);
+
+ return 0;
+}
+
+static int _rsa_key_cmp(const int should_type, const rsa_key *should, const rsa_key *is)
+{
+ if(should_type != is->type)
+ return CRYPT_ERROR;
+ if(should_type == PK_PRIVATE) {
+ if(mp_cmp(should->q, is->q) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->p, is->p) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->qP, is->qP) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->dP, is->dP) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->dQ, is->dQ) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->d, is->d) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ }
+ if(mp_cmp(should->N, is->N) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ if(mp_cmp(should->e, is->e) != LTC_MP_EQ)
+ return CRYPT_ERROR;
+ return CRYPT_OK;
+}
+
+static int _rsa_issue_301(int prng_idx)
+{
+ rsa_key key, key_in;
+ unsigned char buf[4096];
+ unsigned long len;
+
+ DO(rsa_make_key(&yarrow_prng, prng_idx, sizeof(buf)/8, 65537, &key));
+
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+ DO(rsa_import(buf, len, &key_in));
+
+ DO(_rsa_key_cmp(PK_PRIVATE, &key, &key_in));
+ rsa_free(&key_in);
+
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+ DO(rsa_import(buf, len, &key_in));
+
+ DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in));
+ rsa_free(&key_in);
+
+ len = sizeof(buf);
+ DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
+ DO(rsa_import(buf, len, &key_in));
+
+ DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in));
+ rsa_free(&key_in);
+
+ rsa_free(&key);
+ return CRYPT_OK;
+}
+
+int rsa_test(void)
+{
+ unsigned char in[1024], out[1024], tmp[3072];
+ rsa_key key, privKey, pubKey;
+ int hash_idx, prng_idx, stat, stat2, i, err;
+ unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2;
+ static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
+ void* dP;
+ unsigned char* p;
+ unsigned char* p2;
+ unsigned char* p3;
+
+ if (rsa_compat_test() != 0) {
+ return 1;
+ }
+
+ hash_idx = find_hash("sha1");
+ prng_idx = find_prng("yarrow");
+ if (hash_idx == -1 || prng_idx == -1) {
+ fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow");
+ return 1;
+ }
+
+ DO(_rsa_issue_301(prng_idx));
+
+ /* make 10 random key */
+ for (cnt = 0; cnt < 10; cnt++) {
+ DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key));
+ if (mp_count_bits(key.N) != 1024) {
+ fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(key.N));
+
+len = mp_unsigned_bin_size(key.N);
+mp_to_unsigned_bin(key.N, tmp);
+print_hex("N", tmp, len);
+
+len = mp_unsigned_bin_size(key.p);
+mp_to_unsigned_bin(key.p, tmp);
+print_hex("p", tmp, len);
+
+len = mp_unsigned_bin_size(key.q);
+mp_to_unsigned_bin(key.q, tmp);
+print_hex("q", tmp, len);
+
+ return 1;
+ }
+ if (cnt != 9) {
+ rsa_free(&key);
+ }
+ }
+
+ /* encrypt the key (without lparam) */
+ for (cnt = 0; cnt < 4; cnt++) {
+ for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) {
+ /* make a random key/msg */
+ yarrow_read(in, rsa_msgsize, &yarrow_prng);
+
+ len = sizeof(out);
+ len2 = rsa_msgsize;
+
+ DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key));
+ /* change a byte */
+ out[8] ^= 1;
+ DOX((err = rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key))
+ == CRYPT_INVALID_PACKET ? CRYPT_OK:err, "should fail");
+ /* change a byte back */
+ out[8] ^= 1;
+ if (len2 != rsa_msgsize) {
+ fprintf(stderr, "\n%i:rsa_decrypt_key mismatch len %lu (first decrypt)", __LINE__, len2);
+ return 1;
+ }
+
+ len2 = rsa_msgsize;
+ DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_decrypt_key (without lparam) failed (rsa_msgsize = %lu)", rsa_msgsize);
+ fprintf(stderr, "\n stat: %i stat2: %i", stat, stat2);
+ return 1;
+ }
+ if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
+ fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2);
+ print_hex("Original", in, rsa_msgsize);
+ print_hex("Output", tmp, len2);
+ return 1;
+ }
+ }
+ }
+
+ /* encrypt the key (with lparam) */
+ for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) {
+ len = sizeof(out);
+ len2 = rsa_msgsize;
+ DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key));
+ /* change a byte */
+ out[8] ^= 1;
+ DOX((err = rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key))
+ == CRYPT_INVALID_PACKET ? CRYPT_OK:err, "should fail");
+ if (len2 != rsa_msgsize) {
+ fprintf(stderr, "\n%i:rsa_decrypt_key mismatch len %lu (first decrypt)", __LINE__, len2);
+ return 1;
+ }
+ /* change a byte back */
+ out[8] ^= 1;
+
+ len2 = rsa_msgsize;
+ DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key));
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_decrypt_key (with lparam) failed (rsa_msgsize = %lu)", rsa_msgsize);
+ return 1;
+ }
+ if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
+ fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2);
+ print_hex("Original", in, rsa_msgsize);
+ print_hex("Output", tmp, len2);
+ return 1;
+ }
+ }
+
+ /* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */
+ for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) {
+ len = sizeof(out);
+ len2 = rsa_msgsize;
+ /* make a random key/msg */
+ yarrow_read(in, rsa_msgsize, &yarrow_prng);
+ DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_PKCS_1_V1_5, &key));
+
+ len2 = rsa_msgsize;
+ DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_PKCS_1_V1_5, &stat, &key));
+ if (stat != 1) {
+ fprintf(stderr, "rsa_decrypt_key_ex failed, %d, %d", stat, stat2);
+ return 1;
+ }
+ if (len2 != rsa_msgsize) {
+ fprintf(stderr, "rsa_decrypt_key_ex mismatch len %lu", len2);
+ return 1;
+ }
+ if (memcmp(tmp, in, rsa_msgsize)) {
+ fprintf(stderr, "rsa_decrypt_key_ex mismatch data");
+ print_hex("Original", in, rsa_msgsize);
+ print_hex("Output", tmp, rsa_msgsize);
+ return 1;
+ }
+ }
+
+ /* sign a message (unsalted, lower cholestorol and Atkins approved) now */
+ len = sizeof(out);
+ DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key));
+
+/* export key and import as both private and public */
+ len2 = sizeof(tmp);
+ DO(rsa_export(tmp, &len2, PK_PRIVATE, &key));
+ DO(rsa_import(tmp, len2, &privKey));
+ len2 = sizeof(tmp);
+ DO(rsa_export(tmp, &len2, PK_PUBLIC, &key));
+ DO(rsa_import(tmp, len2, &pubKey));
+
+ /* verify with original */
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+
+ /* verify with privKey */
+ /* change byte back to original */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+
+ /* verify with privKey but remove pointer to dP to test without CRT */
+
+ dP = privKey.dP;
+ privKey.dP = NULL;
+ /* change byte back to original */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+ privKey.dP = dP;
+
+ /* verify with pubKey */
+ /* change byte back to original */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+
+ /* sign a message (salted) now (use privKey to make, pubKey to verify) */
+ len = sizeof(out);
+ DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey));
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+
+ /* sign a message with PKCS #1 v1.5 */
+ len = sizeof(out);
+ DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey));
+ DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey));
+ /* change a byte */
+ in[0] ^= 1;
+ DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey));
+
+ if (!(stat == 1 && stat2 == 0)) {
+ fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2);
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 1;
+ }
+
+ /* Testcase for Bleichenbacher attack
+ *
+ * (1) Create a valid signature
+ * (2) Check that it can be verified
+ * (3) Decrypt the package to fetch plain text
+ * (4) Forge the structure of PKCS#1-EMSA encoded data
+ * (4.1) Search for start and end of the padding string
+ * (4.2) Move the signature to the front of the padding string
+ * (4.3) Zero the message until the end
+ * (5) Encrypt the package again
+ * (6) Profit :)
+ * For PS lengths < 8: the verification process should fail
+ * For PS lengths >= 8: the verification process should succeed
+ * For all PS lengths: the result should not be valid
+ */
+
+ p = in;
+ p2 = out;
+ p3 = tmp;
+ for (i = 0; i < 9; ++i) {
+ len = sizeof(in);
+ len2 = sizeof(out);
+ /* (1) */
+ DO(rsa_sign_hash_ex(p, 20, p2, &len2, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey));
+ /* (2) */
+ DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey), "should succeed");
+ DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should succeed");
+ len3 = sizeof(tmp);
+ /* (3) */
+ DO(ltc_mp.rsa_me(p2, len2, p3, &len3, PK_PUBLIC, &key));
+ /* (4) */
+#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
+ print_hex("Original signature", p3, len3);
+#endif
+ /* (4.1) */
+ for (cnt = 0; cnt < len3; ++cnt) {
+ if (p3[cnt] == 0xff)
+ break;
+ }
+ for (cnt2 = cnt+1; cnt2 < len3; ++cnt2) {
+ if (p3[cnt2] != 0xff)
+ break;
+ }
+ /* (4.2) */
+ memmove(&p3[cnt+i], &p3[cnt2], len3-cnt2);
+ /* (4.3) */
+ for (cnt = cnt + len3-cnt2+i; cnt < len; ++cnt) {
+ p3[cnt] = 0;
+ }
+#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
+ print_hex("Forged signature", p3, len3);
+#endif
+
+ len2 = sizeof(out);
+ /* (5) */
+ DO(ltc_mp.rsa_me(p3, len3, p2, &len2, PK_PRIVATE, &key));
+
+ len3 = sizeof(tmp);
+ /* (6) */
+ if (i < 8)
+ DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey)
+ == CRYPT_INVALID_PACKET ? CRYPT_OK:CRYPT_INVALID_PACKET, "should fail");
+ else
+ DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey), "should succeed");
+ DOX(stat == 0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should fail");
+ }
+ rsa_free(&key);
+
+ /* try reading the public RSA key from a X509 certificate */
+ len3 = sizeof(tmp);
+ DO(base64_decode(x509_public_rsa, sizeof(x509_public_rsa), tmp, &len3));
+ DO(rsa_import_x509(tmp, len3, &key));
+ len = sizeof(tmp);
+ DO(rsa_export(tmp, &len, PK_PUBLIC, &key));
+ if (len != sizeof(openssl_public_rsa_stripped) || memcmp(tmp, openssl_public_rsa_stripped, len)) {
+ fprintf(stderr, "RSA public export failed to match rsa_import_x509\n");
+ return 1;
+ }
+ rsa_free(&key);
+
+ len3 = sizeof(tmp);
+ DO(base64_decode(_der_tests_cacert_root_cert, _der_tests_cacert_root_cert_size, tmp, &len3));
+
+ DO(rsa_import_x509(tmp, len3, &key));
+
+ /* free the key and return */
+ rsa_free(&key);
+ rsa_free(&pubKey);
+ rsa_free(&privKey);
+ return 0;
+}
+
+#else
+
+int rsa_test(void)
+{
+ return CRYPT_NOP;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/store_test.c b/libtomcrypt/tests/store_test.c
new file mode 100644
index 0000000..6974ba0
--- /dev/null
+++ b/libtomcrypt/tests/store_test.c
@@ -0,0 +1,86 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+/* Test store/load macros with offsets */
+int store_test(void)
+{
+ unsigned char buf[256];
+ int y;
+ ulong32 L, L1;
+ ulong64 LL, LL1;
+#ifdef LTC_FAST
+ int x, z;
+#endif
+
+ for (y = 0; y < 4; y++) {
+ L = 0x12345678UL;
+ L1 = 0;
+ STORE32L(L, buf + y);
+ LOAD32L(L1, buf + y);
+ if (L1 != L) {
+ fprintf(stderr, "\n32L failed at offset %d\n", y);
+ return 1;
+ }
+ STORE32H(L, buf + y);
+ LOAD32H(L1, buf + y);
+ if (L1 != L) {
+ fprintf(stderr, "\n32H failed at offset %d\n", y);
+ return 1;
+ }
+ }
+
+ for (y = 0; y < 8; y++) {
+ LL = CONST64 (0x01020304050607);
+ LL1 = 0;
+ STORE64L(LL, buf + y);
+ LOAD64L(LL1, buf + y);
+ if (LL1 != LL) {
+ fprintf(stderr, "\n64L failed at offset %d\n", y);
+ return 1;
+ }
+ STORE64H(LL, buf + y);
+ LOAD64H(LL1, buf + y);
+ if (LL1 != LL) {
+ fprintf(stderr, "\n64H failed at offset %d\n", y);
+ return 1;
+ }
+ }
+
+/* test LTC_FAST */
+#ifdef LTC_FAST
+ y = 16;
+
+ for (z = 0; z < y; z++) {
+ /* fill y bytes with random */
+ yarrow_read(buf+z, y, &yarrow_prng);
+ yarrow_read(buf+z+y, y, &yarrow_prng);
+
+ /* now XOR it byte for byte */
+ for (x = 0; x < y; x++) {
+ buf[2*y+z+x] = buf[z+x] ^ buf[z+y+x];
+ }
+
+ /* now XOR it word for word */
+ for (x = 0; x < y; x += sizeof(LTC_FAST_TYPE)) {
+ *(LTC_FAST_TYPE_PTR_CAST(&buf[3*y+z+x])) = *(LTC_FAST_TYPE_PTR_CAST(&buf[z+x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&buf[z+y+x]));
+ }
+
+ if (memcmp(&buf[2*y+z], &buf[3*y+z], y)) {
+ fprintf(stderr, "\nLTC_FAST failed at offset %d\n", z);
+ return 1;
+ }
+ }
+#endif
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/test.c b/libtomcrypt/tests/test.c
new file mode 100644
index 0000000..c744849
--- /dev/null
+++ b/libtomcrypt/tests/test.c
@@ -0,0 +1,433 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt_test.h>
+
+#ifndef GIT_VERSION
+#define GIT_VERSION "Undefined version"
+#endif
+
+#define LTC_TEST_FN(f) { f, #f }
+
+typedef struct {
+ int (*fn)(void);
+ const char* name;
+} test_function;
+
+static const test_function test_functions[] =
+{
+ LTC_TEST_FN(store_test),
+ LTC_TEST_FN(rotate_test),
+ LTC_TEST_FN(misc_test),
+ LTC_TEST_FN(mpi_test),
+ LTC_TEST_FN(cipher_hash_test),
+ LTC_TEST_FN(mac_test),
+ LTC_TEST_FN(modes_test),
+ LTC_TEST_FN(der_test),
+ LTC_TEST_FN(pkcs_1_test),
+ LTC_TEST_FN(pkcs_1_pss_test),
+ LTC_TEST_FN(pkcs_1_oaep_test),
+ LTC_TEST_FN(pkcs_1_emsa_test),
+ LTC_TEST_FN(pkcs_1_eme_test),
+ LTC_TEST_FN(rsa_test),
+ LTC_TEST_FN(dh_test),
+ LTC_TEST_FN(ecc_tests),
+ LTC_TEST_FN(dsa_test),
+ LTC_TEST_FN(katja_test),
+ LTC_TEST_FN(file_test),
+ LTC_TEST_FN(multi_test),
+ /* keep the prng_test always at the end as
+ * it has to be handled specially when
+ * testing with LTC_PTHREAD enabled
+ */
+ LTC_TEST_FN(prng_test),
+};
+
+
+#if defined(_WIN32)
+ #include <windows.h> /* GetSystemTimeAsFileTime */
+#else
+ #include <sys/time.h>
+#endif
+
+/* microseconds since 1970 (UNIX epoch) */
+static ulong64 epoch_usec(void)
+{
+#if defined(LTC_NO_TEST_TIMING)
+ return 0;
+#elif defined(_WIN32)
+ FILETIME CurrentTime;
+ ulong64 cur_time;
+ ULARGE_INTEGER ul;
+ GetSystemTimeAsFileTime(&CurrentTime);
+ ul.LowPart = CurrentTime.dwLowDateTime;
+ ul.HighPart = CurrentTime.dwHighDateTime;
+ cur_time = ul.QuadPart;
+ cur_time -= CONST64(116444736000000000); /* subtract epoch in microseconds */
+ cur_time /= 10; /* nanoseconds > microseconds */
+ return cur_time;
+#else
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (ulong64)(tv.tv_sec) * 1000000 + (ulong64)(tv.tv_usec); /* get microseconds */
+#endif
+}
+
+#ifdef LTC_PTHREAD
+typedef struct
+{
+ pthread_t thread_id;
+ const test_function* t;
+ int err;
+ ulong64 delta;
+} thread_info;
+
+static void *run(void *arg)
+{
+ thread_info *tinfo = arg;
+ ulong64 ts;
+
+ ts = epoch_usec();
+ tinfo->err = tinfo->t->fn();
+ tinfo->delta = epoch_usec() - ts;
+
+ return arg;
+}
+#endif
+
+
+/*
+ * unregister ciphers, hashes & prngs
+ */
+static void _unregister_all(void)
+{
+#ifdef LTC_RIJNDAEL
+#ifdef ENCRYPT_ONLY
+ /* alternative would be
+ * unregister_cipher(&rijndael_enc_desc);
+ */
+ unregister_cipher(&aes_enc_desc);
+#else
+ /* alternative would be
+ * unregister_cipher(&rijndael_desc);
+ */
+ unregister_cipher(&aes_desc);
+#endif
+#endif
+#ifdef LTC_BLOWFISH
+ unregister_cipher(&blowfish_desc);
+#endif
+#ifdef LTC_XTEA
+ unregister_cipher(&xtea_desc);
+#endif
+#ifdef LTC_RC5
+ unregister_cipher(&rc5_desc);
+#endif
+#ifdef LTC_RC6
+ unregister_cipher(&rc6_desc);
+#endif
+#ifdef LTC_SAFERP
+ unregister_cipher(&saferp_desc);
+#endif
+#ifdef LTC_TWOFISH
+ unregister_cipher(&twofish_desc);
+#endif
+#ifdef LTC_SAFER
+ unregister_cipher(&safer_k64_desc);
+ unregister_cipher(&safer_sk64_desc);
+ unregister_cipher(&safer_k128_desc);
+ unregister_cipher(&safer_sk128_desc);
+#endif
+#ifdef LTC_RC2
+ unregister_cipher(&rc2_desc);
+#endif
+#ifdef LTC_DES
+ unregister_cipher(&des_desc);
+ unregister_cipher(&des3_desc);
+#endif
+#ifdef LTC_CAST5
+ unregister_cipher(&cast5_desc);
+#endif
+#ifdef LTC_NOEKEON
+ unregister_cipher(&noekeon_desc);
+#endif
+#ifdef LTC_SKIPJACK
+ unregister_cipher(&skipjack_desc);
+#endif
+#ifdef LTC_KHAZAD
+ unregister_cipher(&khazad_desc);
+#endif
+#ifdef LTC_ANUBIS
+ unregister_cipher(&anubis_desc);
+#endif
+#ifdef LTC_KSEED
+ unregister_cipher(&kseed_desc);
+#endif
+#ifdef LTC_KASUMI
+ unregister_cipher(&kasumi_desc);
+#endif
+#ifdef LTC_MULTI2
+ unregister_cipher(&multi2_desc);
+#endif
+#ifdef LTC_CAMELLIA
+ unregister_cipher(&camellia_desc);
+#endif
+
+#ifdef LTC_TIGER
+ unregister_hash(&tiger_desc);
+#endif
+#ifdef LTC_MD2
+ unregister_hash(&md2_desc);
+#endif
+#ifdef LTC_MD4
+ unregister_hash(&md4_desc);
+#endif
+#ifdef LTC_MD5
+ unregister_hash(&md5_desc);
+#endif
+#ifdef LTC_SHA1
+ unregister_hash(&sha1_desc);
+#endif
+#ifdef LTC_SHA224
+ unregister_hash(&sha224_desc);
+#endif
+#ifdef LTC_SHA256
+ unregister_hash(&sha256_desc);
+#endif
+#ifdef LTC_SHA384
+ unregister_hash(&sha384_desc);
+#endif
+#ifdef LTC_SHA512
+ unregister_hash(&sha512_desc);
+#endif
+#ifdef LTC_SHA512_224
+ unregister_hash(&sha512_224_desc);
+#endif
+#ifdef LTC_SHA512_256
+ unregister_hash(&sha512_256_desc);
+#endif
+#ifdef LTC_SHA3
+ unregister_hash(&sha3_224_desc);
+ unregister_hash(&sha3_256_desc);
+ unregister_hash(&sha3_384_desc);
+ unregister_hash(&sha3_512_desc);
+#endif
+#ifdef LTC_RIPEMD128
+ unregister_hash(&rmd128_desc);
+#endif
+#ifdef LTC_RIPEMD160
+ unregister_hash(&rmd160_desc);
+#endif
+#ifdef LTC_RIPEMD256
+ unregister_hash(&rmd256_desc);
+#endif
+#ifdef LTC_RIPEMD320
+ unregister_hash(&rmd320_desc);
+#endif
+#ifdef LTC_WHIRLPOOL
+ unregister_hash(&whirlpool_desc);
+#endif
+#ifdef LTC_BLAKE2S
+ unregister_hash(&blake2s_128_desc);
+ unregister_hash(&blake2s_160_desc);
+ unregister_hash(&blake2s_224_desc);
+ unregister_hash(&blake2s_256_desc);
+#endif
+#ifdef LTC_BLAKE2B
+ unregister_hash(&blake2b_160_desc);
+ unregister_hash(&blake2b_256_desc);
+ unregister_hash(&blake2b_384_desc);
+ unregister_hash(&blake2b_512_desc);
+#endif
+#ifdef LTC_CHC_HASH
+ unregister_hash(&chc_desc);
+#endif
+
+ unregister_prng(&yarrow_desc);
+#ifdef LTC_FORTUNA
+ unregister_prng(&fortuna_desc);
+#endif
+#ifdef LTC_RC4
+ unregister_prng(&rc4_desc);
+#endif
+#ifdef LTC_CHACHA20_PRNG
+ unregister_prng(&chacha20_prng_desc);
+#endif
+#ifdef LTC_SOBER128
+ unregister_prng(&sober128_desc);
+#endif
+#ifdef LTC_SPRNG
+ unregister_prng(&sprng_desc);
+#endif
+} /* _cleanup() */
+
+static void register_algs(void)
+{
+ int err;
+
+ atexit(_unregister_all);
+
+#ifndef LTC_YARROW
+ #error This demo requires Yarrow.
+#endif
+ if ((err = register_all_ciphers()) != CRYPT_OK) {
+ fprintf(stderr, "register_all_ciphers err=%s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = register_all_hashes()) != CRYPT_OK) {
+ fprintf(stderr, "register_all_hashes err=%s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = register_all_prngs()) != CRYPT_OK) {
+ fprintf(stderr, "register_all_prngs err=%s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) {
+ fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ if (strcmp("CRYPT_OK", error_to_string(err))) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(int argc, char **argv)
+{
+#ifdef LTC_PTHREAD
+ thread_info *tinfo, *res;
+#endif
+ int x, pass = 0, fail = 0, nop = 0;
+ size_t fn_len, i, dots;
+ char *single_test = NULL;
+ ulong64 ts;
+ long delta, dur, real = 0;
+ register_algs();
+
+ printf("LTC_VERSION = %s\n%s\n\n", GIT_VERSION, crypt_build_settings);
+
+#ifdef USE_LTM
+ ltc_mp = ltm_desc;
+ printf("MP_PROVIDER = LibTomMath\n");
+#elif defined(USE_TFM)
+ ltc_mp = tfm_desc;
+ printf("MP_PROVIDER = TomsFastMath\n");
+#elif defined(USE_GMP)
+ ltc_mp = gmp_desc;
+ printf("MP_PROVIDER = GnuMP\n");
+#elif defined(EXT_MATH_LIB)
+ {
+ extern ltc_math_descriptor EXT_MATH_LIB;
+ ltc_mp = EXT_MATH_LIB;
+ }
+
+#define NAME_VALUE(s) #s"="NAME(s)
+#define NAME(s) #s
+ printf("MP_PROVIDER = %s\n", NAME_VALUE(EXT_MATH_LIB));
+#undef NAME_VALUE
+#undef NAME
+
+#endif
+#ifdef LTC_TEST_MPI
+ printf("MP_DIGIT_BIT = %d\n", MP_DIGIT_BIT);
+#else
+ printf("NO math provider selected, all tests requiring MPI were disabled and will 'nop'\n");
+#endif
+
+ printf("sizeof(ltc_mp_digit) = %d\n", (int)sizeof(ltc_mp_digit));
+
+#ifdef LTC_PTHREAD
+ tinfo = XCALLOC(sizeof(test_functions)/sizeof(test_functions[0]), sizeof(thread_info));
+ if (tinfo == NULL) {
+ printf("\n\nFAILURE: XCALLOC\n");
+ return EXIT_FAILURE;
+ }
+#endif
+
+ fn_len = 0;
+ for (i = 0; i < sizeof(test_functions) / sizeof(test_functions[0]); ++i) {
+ size_t len = strlen(test_functions[i].name);
+ if (fn_len < len) fn_len = len;
+
+#ifdef LTC_PTHREAD
+ if(test_functions[i].fn == prng_test) continue;
+ tinfo[i].t = &test_functions[i];
+ x = pthread_create(&tinfo[i].thread_id, NULL, run, &tinfo[i]);
+ if (x != 0) {
+ printf("\n\nFAILURE: pthread_create\n");
+ return EXIT_FAILURE;
+ }
+#endif
+ }
+
+ fn_len = fn_len + (4 - (fn_len % 4));
+
+ /* single test name from commandline */
+ if (argc > 1) single_test = argv[1];
+
+ dur = epoch_usec();
+ for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
+ if (single_test && strstr(test_functions[i].name, single_test) == NULL) {
+ continue;
+ }
+ dots = fn_len - strlen(test_functions[i].name);
+
+ printf("\n%s", test_functions[i].name);
+ while(dots--) printf(".");
+ fflush(stdout);
+
+#ifdef LTC_PTHREAD
+ if(test_functions[i].fn != prng_test) {
+ x = pthread_join(tinfo[i].thread_id, (void**)&res);
+ if (x != 0){
+ printf("\n\nFAILURE: pthread_join\n");
+ return EXIT_FAILURE;
+ }
+ x = res->err;
+ delta = res->delta;
+ }
+ else {
+ ts = epoch_usec();
+ x = test_functions[i].fn();
+ delta = (long)(epoch_usec() - ts);
+ }
+#else
+ ts = epoch_usec();
+ x = test_functions[i].fn();
+ delta = (long)(epoch_usec() - ts);
+#endif
+ real += delta;
+
+ if (x == CRYPT_OK) {
+ printf("passed %10.3fms", (double)(delta)/1000);
+ pass++;
+ }
+ else if (x == CRYPT_NOP) {
+ printf("nop");
+ nop++;
+ }
+ else {
+ printf("failed (%s) %10.3fms", error_to_string(x), (double)(delta)/1000);
+ fail++;
+ }
+ }
+ dur = epoch_usec() - dur;
+
+#ifdef LTC_PTHREAD
+ XFREE(tinfo);
+#endif
+
+ x = (fail > 0 || fail+pass+nop == 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+ printf("\n\n%s: passed=%d failed=%d nop=%d duration=%.1fsec real=%.1fsec\n", x ? "FAILURE" : "SUCCESS", pass, fail, nop, (double)(dur)/(1000*1000), (double)(real)/(1000*1000));
+ return x;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/tests/test.der b/libtomcrypt/tests/test.der
new file mode 100644
index 0000000..d7041f9
--- /dev/null
+++ b/libtomcrypt/tests/test.der
Binary files differ
diff --git a/libtomcrypt/tests/test.key b/libtomcrypt/tests/test.key
new file mode 100644
index 0000000..e4996c3
--- /dev/null
+++ b/libtomcrypt/tests/test.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97bfYUtlmXl
+P3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7kEY5BaHxh
+E9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE/QIDAQAB
+AoGBAMhiuereRFMdVpfZl54azzAeCohFhikwo02fYWVz4NaHj7bzBqOC3Hys/pso
+mq79+/4vDtiXBOO7H9HsDbqjSX9HrIpEBH6GtzlCP60etw6lUfRAYx79veqfQZ+o
+kB1vClqVExENgK9fZJiKLHhoZbAri6JTh8rxZASr8nvbg8iBAkEA975eI8MyP7+L
+jjru/PzL5ffxC7xCgq7Vej7K99VpP2Qloh+3dXUFkkLruPHzCgXjlNFVeDWgNqCb
+fJKEbN3cTQJBANaGDoVCCwQIhCFg8A4NiP0eNhBlTx5TtAhygFw/WWYX5pjy6Wx6
+Bkysdj3tjKHOrRu9tH0ovOMOOI2Z2AW1o3ECQG3rwy0u8F6kiDEFKQCK0ZUpm4PP
+ddsx43on3jp0MAx2TNRQKkAtOdmZY6ldgK5TypQ/BSMe+AUE4bg18hezoIkCQQCr
+kIj6YAgpUJpDi6BQzNha/pdkY3F0IqMgAlrP68YWlVTRy6uNGsYA+giSnHHVUlI1
+lnFLi5IM0Om/rWMLpemxAkEA3MwnyOTcYkjVm6/1q2D2If1T4rddCckaoQSp/GEs
+XQRYOlo58UohVmf9zCCjj3gYWnk9Lo5+hgrmqDPBBBdKnw==
+-----END RSA PRIVATE KEY-----
diff --git a/libtomcrypt/tests/test_dsa.key b/libtomcrypt/tests/test_dsa.key
new file mode 100644
index 0000000..2f02669
--- /dev/null
+++ b/libtomcrypt/tests/test_dsa.key
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDFCjdRXKvWGNWicL1Kb2tK+eE5lQ8rmTh9mmTWTLWWetztrKis
+xhtlWt7bAGElGhgs7qEHkGJeTRIxkMcDIfoJ57Fz146v2/2/s++t0aEqA23nBpJK
+hSr/egFmUx/qxmdBhFrAbO1i+cJiYgWk+kigZuw1yagR/rmBq+6+Mba/zwIVAKpb
+1/TlBiQT5Yg1ygDHpjVxYZTFAoGAO5Lk/1kpFQsImVp78q0UQFVvoEf/kJmzRLPU
+/EUVBa5nIkOcujcQpYlHN+zM9a6tqLR6Ncudk1zt5rB+lpTEpgx91nCKCU+BSg7C
+E/vrFr/qpPRW/3IwBd6KRD++xoUmVdYtHR7bFdqkRYM8F5eYC42H80kNkL2pq2du
+h2hyI9wCgYBTFrD7v1mKXlWVwU+sQ7gIU+bPDZIj+rGEWVI5v8vyLTg63ZNSBUl+
+KxLEYXPjb1S9luWnqqlaWKS3Z9LAvcgesToST5jABe85XWq6tws72LeV3XluotKE
+c0cDiLRk2bm4T/HJNLv5c2b1fC4R/sMx5gg4WWeB621BJ9cNdK+gNQIVAJk25eTp
++yi+kfUGX+jJNbP12B/F
+-----END DSA PRIVATE KEY-----
diff --git a/libtomcrypt/tests/tomcrypt_test.h b/libtomcrypt/tests/tomcrypt_test.h
new file mode 100644
index 0000000..bc1e02b
--- /dev/null
+++ b/libtomcrypt/tests/tomcrypt_test.h
@@ -0,0 +1,69 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#ifndef __TEST_H_
+#define __TEST_H_
+
+#include <tomcrypt.h>
+
+#include "common.h"
+
+#ifdef USE_LTM
+/* Use libtommath as MPI provider */
+#define LTC_TEST_MPI
+#elif defined(USE_TFM)
+/* Use tomsfastmath as MPI provider */
+#define LTC_TEST_MPI
+#elif defined(USE_GMP)
+/* Use GNU Multiple Precision Arithmetic Library as MPI provider */
+#define LTC_TEST_MPI
+#elif defined(EXT_MATH_LIB)
+/* The user must define his own MPI provider! */
+#define LTC_TEST_MPI
+#endif
+
+typedef struct {
+ char *name, *prov, *req;
+ int (*entry)(void);
+} test_entry;
+
+/* TESTS */
+int cipher_hash_test(void);
+int modes_test(void);
+int mac_test(void);
+int pkcs_1_test(void);
+int pkcs_1_pss_test(void);
+int pkcs_1_oaep_test(void);
+int pkcs_1_emsa_test(void);
+int pkcs_1_eme_test(void);
+int store_test(void);
+int rotate_test(void);
+int rsa_test(void);
+int dh_test(void);
+int katja_test(void);
+int ecc_tests(void);
+int dsa_test(void);
+int der_test(void);
+int misc_test(void);
+int base64_test(void);
+int file_test(void);
+int multi_test(void);
+int prng_test(void);
+int mpi_test(void);
+
+#ifdef LTC_PKCS_1
+struct ltc_prng_descriptor* no_prng_desc_get(void);
+void no_prng_desc_free(struct ltc_prng_descriptor*);
+#endif
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */