aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test_crypto.c')
-rw-r--r--src/test/test_crypto.c574
1 files changed, 509 insertions, 65 deletions
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 7f4347a41..5d8edb655 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1,13 +1,22 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2012, The Tor Project, Inc. */
+ * Copyright (c) 2007-2013, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#define CRYPTO_PRIVATE
+#define CRYPTO_CURVE25519_PRIVATE
#include "or.h"
#include "test.h"
#include "aes.h"
+#include "util.h"
+#include "siphash.h"
+#ifdef CURVE25519_ENABLED
+#include "crypto_curve25519.h"
+#endif
+
+extern const char AUTHORITY_SIGNKEY_3[];
+extern const char AUTHORITY_SIGNKEY_A_DIGEST[];
+extern const char AUTHORITY_SIGNKEY_A_DIGEST256[];
/** Run unit tests for Diffie-Hellman functionality. */
static void
@@ -119,9 +128,9 @@ test_crypto_aes(void *arg)
memset(data2, 0, 1024);
memset(data3, 0, 1024);
env1 = crypto_cipher_new(NULL);
- test_neq(env1, 0);
+ test_neq_ptr(env1, 0);
env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
- test_neq(env2, 0);
+ test_neq_ptr(env2, 0);
/* Try encrypting 512 chars. */
crypto_cipher_encrypt(env1, data2, data1, 512);
@@ -152,7 +161,7 @@ test_crypto_aes(void *arg)
memset(data3, 0, 1024);
env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
- test_neq(env2, 0);
+ test_neq_ptr(env2, NULL);
for (j = 0; j < 1024-16; j += 17) {
crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
}
@@ -264,34 +273,6 @@ test_crypto_sha(void)
"96177A9CB410FF61F20015AD");
tt_int_op(i, ==, 0);
- /* Test HMAC-SHA-1 with test cases from RFC2202. */
-
- /* Case 1. */
- memset(key, 0x0b, 20);
- crypto_hmac_sha1(digest, key, 20, "Hi There", 8);
- test_streq(hex_str(digest, 20),
- "B617318655057264E28BC0B6FB378C8EF146BE00");
- /* Case 2. */
- crypto_hmac_sha1(digest, "Jefe", 4, "what do ya want for nothing?", 28);
- test_streq(hex_str(digest, 20),
- "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79");
-
- /* Case 4. */
- base16_decode(key, 25,
- "0102030405060708090a0b0c0d0e0f10111213141516171819", 50);
- memset(data, 0xcd, 50);
- crypto_hmac_sha1(digest, key, 25, data, 50);
- test_streq(hex_str(digest, 20),
- "4C9007F4026250C6BC8414F9BF50C86C2D7235DA");
-
- /* Case 5. */
- memset(key, 0xaa, 80);
- crypto_hmac_sha1(digest, key, 80,
- "Test Using Larger Than Block-Size Key - Hash Key First",
- 54);
- test_streq(hex_str(digest, 20),
- "AA4AE5E15272D00E95705637CE8A3B55ED402112");
-
/* Test HMAC-SHA256 with test cases from wikipedia and RFC 4231 */
/* Case empty (wikipedia) */
@@ -417,7 +398,7 @@ test_crypto_pk(void)
char *encoded = NULL;
char data1[1024], data2[1024], data3[1024];
size_t size;
- int i, j, p, len;
+ int i, len;
/* Public-key ciphers */
pk1 = pk_generate(0);
@@ -427,6 +408,11 @@ test_crypto_pk(void)
test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
+ /* comparison between keys and NULL */
+ tt_int_op(crypto_pk_cmp_keys(NULL, pk1), <, 0);
+ tt_int_op(crypto_pk_cmp_keys(NULL, NULL), ==, 0);
+ tt_int_op(crypto_pk_cmp_keys(pk1, NULL), >, 0);
+
test_eq(128, crypto_pk_keysize(pk1));
test_eq(1024, crypto_pk_num_bits(pk1));
test_eq(128, crypto_pk_keysize(pk2));
@@ -496,19 +482,16 @@ test_crypto_pk(void)
/* Try with hybrid encryption wrappers. */
crypto_rand(data1, 1024);
- for (i = 0; i < 2; ++i) {
- for (j = 85; j < 140; ++j) {
- memset(data2,0,1024);
- memset(data3,0,1024);
- p = (i==0)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
- len = crypto_pk_public_hybrid_encrypt(pk1,data2,sizeof(data2),
- data1,j,p,0);
- test_assert(len>=0);
- len = crypto_pk_private_hybrid_decrypt(pk1,data3,sizeof(data3),
- data2,len,p,1);
- test_eq(len,j);
- test_memeq(data1,data3,j);
- }
+ for (i = 85; i < 140; ++i) {
+ memset(data2,0,1024);
+ memset(data3,0,1024);
+ len = crypto_pk_public_hybrid_encrypt(pk1,data2,sizeof(data2),
+ data1,i,PK_PKCS1_OAEP_PADDING,0);
+ test_assert(len>=0);
+ len = crypto_pk_private_hybrid_decrypt(pk1,data3,sizeof(data3),
+ data2,len,PK_PKCS1_OAEP_PADDING,1);
+ test_eq(len,i);
+ test_memeq(data1,data3,i);
}
/* Try copy_full */
@@ -526,6 +509,85 @@ test_crypto_pk(void)
tor_free(encoded);
}
+static void
+test_crypto_pk_fingerprints(void *arg)
+{
+ crypto_pk_t *pk = NULL;
+ char encoded[512];
+ char d[DIGEST_LEN], d2[DIGEST_LEN];
+ char fingerprint[FINGERPRINT_LEN+1];
+ int n;
+ unsigned i;
+ char *mem_op_hex_tmp=NULL;
+
+ (void)arg;
+
+ pk = pk_generate(1);
+ tt_assert(pk);
+ n = crypto_pk_asn1_encode(pk, encoded, sizeof(encoded));
+ tt_int_op(n, >, 0);
+ tt_int_op(n, >, 128);
+ tt_int_op(n, <, 256);
+
+ /* Is digest as expected? */
+ crypto_digest(d, encoded, n);
+ tt_int_op(0, ==, crypto_pk_get_digest(pk, d2));
+ test_memeq(d, d2, DIGEST_LEN);
+
+ /* Is fingerprint right? */
+ tt_int_op(0, ==, crypto_pk_get_fingerprint(pk, fingerprint, 0));
+ tt_int_op(strlen(fingerprint), ==, DIGEST_LEN * 2);
+ test_memeq_hex(d, fingerprint);
+
+ /* Are spaces right? */
+ tt_int_op(0, ==, crypto_pk_get_fingerprint(pk, fingerprint, 1));
+ for (i = 4; i < strlen(fingerprint); i += 5) {
+ tt_int_op(fingerprint[i], ==, ' ');
+ }
+ tor_strstrip(fingerprint, " ");
+ tt_int_op(strlen(fingerprint), ==, DIGEST_LEN * 2);
+ test_memeq_hex(d, fingerprint);
+
+ /* Now hash again and check crypto_pk_get_hashed_fingerprint. */
+ crypto_digest(d2, d, sizeof(d));
+ tt_int_op(0, ==, crypto_pk_get_hashed_fingerprint(pk, fingerprint));
+ tt_int_op(strlen(fingerprint), ==, DIGEST_LEN * 2);
+ test_memeq_hex(d2, fingerprint);
+
+ done:
+ crypto_pk_free(pk);
+ tor_free(mem_op_hex_tmp);
+}
+
+/** Sanity check for crypto pk digests */
+static void
+test_crypto_digests(void)
+{
+ crypto_pk_t *k = NULL;
+ ssize_t r;
+ digests_t pkey_digests;
+ char digest[DIGEST_LEN];
+
+ k = crypto_pk_new();
+ test_assert(k);
+ r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3, -1);
+ test_assert(!r);
+
+ r = crypto_pk_get_digest(k, digest);
+ test_assert(r == 0);
+ test_memeq(hex_str(digest, DIGEST_LEN),
+ AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN);
+
+ r = crypto_pk_get_all_digests(k, &pkey_digests);
+
+ test_memeq(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN),
+ AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN);
+ test_memeq(hex_str(pkey_digests.d[DIGEST_SHA256], DIGEST256_LEN),
+ AUTHORITY_SIGNKEY_A_DIGEST256, HEX_DIGEST256_LEN);
+ done:
+ crypto_pk_free(k);
+}
+
/** Run unit tests for misc crypto formatting functionality (base64, base32,
* fingerprints, etc) */
static void
@@ -620,28 +682,12 @@ test_crypto_formats(void)
data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
test_eq(strlen(data1), 40);
data2 = tor_malloc(FINGERPRINT_LEN+1);
- add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
+ crypto_add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
tor_free(data1);
tor_free(data2);
}
- /* Check fingerprint */
- {
- test_assert(crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 0000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ABCD 1234 ABCD 5678 0000 ABCD1234 ABCD 5678 00000"));
- test_assert(!crypto_pk_check_fingerprint_syntax(
- "ACD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 00000"));
- }
-
done:
tor_free(data1);
tor_free(data2);
@@ -736,11 +782,13 @@ test_crypto_aes_iv(void *arg)
/* Decrypt with the wrong key. */
decrypted_size = crypto_cipher_decrypt_with_iv(key2, decrypted2, 4095,
encrypted1, encrypted_size);
- test_memneq(plain, decrypted2, encrypted_size);
+ test_eq(decrypted_size, 4095);
+ test_memneq(plain, decrypted2, decrypted_size);
/* Alter the initialization vector. */
encrypted1[0] += 42;
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095,
encrypted1, encrypted_size);
+ test_eq(decrypted_size, 4095);
test_memneq(plain, decrypted2, 4095);
/* Special length case: 1. */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 1,
@@ -827,6 +875,390 @@ test_crypto_base32_decode(void)
;
}
+static void
+test_crypto_kdf_TAP(void *arg)
+{
+ uint8_t key_material[100];
+ int r;
+ char *mem_op_hex_tmp = NULL;
+
+ (void)arg;
+#define EXPAND(s) \
+ r = crypto_expand_key_material_TAP( \
+ (const uint8_t*)(s), strlen(s), \
+ key_material, 100)
+
+ /* Test vectors generated with a little python script; feel free to write
+ * your own. */
+ memset(key_material, 0, sizeof(key_material));
+ EXPAND("");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "5ba93c9db0cff93f52b521d7420e43f6eda2784fbf8b4530d8"
+ "d246dd74ac53a13471bba17941dff7c4ea21bb365bbeeaf5f2"
+ "c654883e56d11e43c44e9842926af7ca0a8cca12604f945414"
+ "f07b01e13da42c6cf1de3abfdea9b95f34687cbbe92b9a7383");
+
+ EXPAND("Tor");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "776c6214fc647aaa5f683c737ee66ec44f03d0372e1cce6922"
+ "7950f236ddf1e329a7ce7c227903303f525a8c6662426e8034"
+ "870642a6dabbd41b5d97ec9bf2312ea729992f48f8ea2d0ba8"
+ "3f45dfda1a80bdc8b80de01b23e3e0ffae099b3e4ccf28dc28");
+
+ EXPAND("AN ALARMING ITEM TO FIND ON A MONTHLY AUTO-DEBIT NOTICE");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "a340b5d126086c3ab29c2af4179196dbf95e1c72431419d331"
+ "4844bf8f6afb6098db952b95581fb6c33625709d6f4400b8e7"
+ "ace18a70579fad83c0982ef73f89395bcc39493ad53a685854"
+ "daf2ba9b78733b805d9a6824c907ee1dba5ac27a1e466d4d10");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+
+#undef EXPAND
+}
+
+static void
+test_crypto_hkdf_sha256(void *arg)
+{
+ uint8_t key_material[100];
+ const uint8_t salt[] = "ntor-curve25519-sha256-1:key_extract";
+ const size_t salt_len = strlen((char*)salt);
+ const uint8_t m_expand[] = "ntor-curve25519-sha256-1:key_expand";
+ const size_t m_expand_len = strlen((char*)m_expand);
+ int r;
+ char *mem_op_hex_tmp = NULL;
+
+ (void)arg;
+
+#define EXPAND(s) \
+ r = crypto_expand_key_material_rfc5869_sha256( \
+ (const uint8_t*)(s), strlen(s), \
+ salt, salt_len, \
+ m_expand, m_expand_len, \
+ key_material, 100)
+
+ /* Test vectors generated with ntor_ref.py */
+ memset(key_material, 0, sizeof(key_material));
+ EXPAND("");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "d3490ed48b12a48f9547861583573fe3f19aafe3f81dc7fc75"
+ "eeed96d741b3290f941576c1f9f0b2d463d1ec7ab2c6bf71cd"
+ "d7f826c6298c00dbfe6711635d7005f0269493edf6046cc7e7"
+ "dcf6abe0d20c77cf363e8ffe358927817a3d3e73712cee28d8");
+
+ EXPAND("Tor");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "5521492a85139a8d9107a2d5c0d9c91610d0f95989975ebee6"
+ "c02a4f8d622a6cfdf9b7c7edd3832e2760ded1eac309b76f8d"
+ "66c4a3c4d6225429b3a016e3c3d45911152fc87bc2de9630c3"
+ "961be9fdb9f93197ea8e5977180801926d3321fa21513e59ac");
+
+ EXPAND("AN ALARMING ITEM TO FIND ON YOUR CREDIT-RATING STATEMENT");
+ tt_int_op(r, ==, 0);
+ test_memeq_hex(key_material,
+ "a2aa9b50da7e481d30463adb8f233ff06e9571a0ca6ab6df0f"
+ "b206fa34e5bc78d063fc291501beec53b36e5a0e434561200c"
+ "5f8bd13e0f88b3459600b4dc21d69363e2895321c06184879d"
+ "94b18f078411be70b767c7fc40679a9440a0c95ea83a23efbf");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+#undef EXPAND
+}
+
+#ifdef CURVE25519_ENABLED
+static void
+test_crypto_curve25519_impl(void *arg)
+{
+ /* adapted from curve25519_donna, which adapted it from test-curve25519
+ version 20050915, by D. J. Bernstein, Public domain. */
+
+ const int randomize_high_bit = (arg != NULL);
+
+#ifdef SLOW_CURVE25519_TEST
+ const int loop_max=10000;
+ const char e1_expected[] = "4faf81190869fd742a33691b0e0824d5"
+ "7e0329f4dd2819f5f32d130f1296b500";
+ const char e2k_expected[] = "05aec13f92286f3a781ccae98995a3b9"
+ "e0544770bc7de853b38f9100489e3e79";
+ const char e1e2k_expected[] = "cd6e8269104eb5aaee886bd2071fba88"
+ "bd13861475516bc2cd2b6e005e805064";
+#else
+ const int loop_max=200;
+ const char e1_expected[] = "bc7112cde03f97ef7008cad1bdc56be3"
+ "c6a1037d74cceb3712e9206871dcf654";
+ const char e2k_expected[] = "dd8fa254fb60bdb5142fe05b1f5de44d"
+ "8e3ee1a63c7d14274ea5d4c67f065467";
+ const char e1e2k_expected[] = "7ddb98bd89025d2347776b33901b3e7e"
+ "c0ee98cb2257a4545c0cfb2ca3e1812b";
+#endif
+
+ unsigned char e1k[32];
+ unsigned char e2k[32];
+ unsigned char e1e2k[32];
+ unsigned char e2e1k[32];
+ unsigned char e1[32] = {3};
+ unsigned char e2[32] = {5};
+ unsigned char k[32] = {9};
+ int loop, i;
+
+ char *mem_op_hex_tmp = NULL;
+
+ for (loop = 0; loop < loop_max; ++loop) {
+ curve25519_impl(e1k,e1,k);
+ curve25519_impl(e2e1k,e2,e1k);
+ curve25519_impl(e2k,e2,k);
+ if (randomize_high_bit) {
+ /* We require that the high bit of the public key be ignored. So if
+ * we're doing this variant test, we randomize the high bit of e2k, and
+ * make sure that the handshake still works out the same as it would
+ * otherwise. */
+ uint8_t byte;
+ crypto_rand((char*)&byte, 1);
+ e2k[31] |= (byte & 0x80);
+ }
+ curve25519_impl(e1e2k,e1,e2k);
+ test_memeq(e1e2k, e2e1k, 32);
+ if (loop == loop_max-1) {
+ break;
+ }
+ for (i = 0;i < 32;++i) e1[i] ^= e2k[i];
+ for (i = 0;i < 32;++i) e2[i] ^= e1k[i];
+ for (i = 0;i < 32;++i) k[i] ^= e1e2k[i];
+ }
+
+ test_memeq_hex(e1, e1_expected);
+ test_memeq_hex(e2k, e2k_expected);
+ test_memeq_hex(e1e2k, e1e2k_expected);
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_curve25519_wrappers(void *arg)
+{
+ curve25519_public_key_t pubkey1, pubkey2;
+ curve25519_secret_key_t seckey1, seckey2;
+
+ uint8_t output1[CURVE25519_OUTPUT_LEN];
+ uint8_t output2[CURVE25519_OUTPUT_LEN];
+ (void)arg;
+
+ /* Test a simple handshake, serializing and deserializing some stuff. */
+ curve25519_secret_key_generate(&seckey1, 0);
+ curve25519_secret_key_generate(&seckey2, 1);
+ curve25519_public_key_generate(&pubkey1, &seckey1);
+ curve25519_public_key_generate(&pubkey2, &seckey2);
+ test_assert(curve25519_public_key_is_ok(&pubkey1));
+ test_assert(curve25519_public_key_is_ok(&pubkey2));
+ curve25519_handshake(output1, &seckey1, &pubkey2);
+ curve25519_handshake(output2, &seckey2, &pubkey1);
+ test_memeq(output1, output2, sizeof(output1));
+
+ done:
+ ;
+}
+
+static void
+test_crypto_curve25519_encode(void *arg)
+{
+ curve25519_secret_key_t seckey;
+ curve25519_public_key_t key1, key2, key3;
+ char buf[64];
+
+ (void)arg;
+
+ curve25519_secret_key_generate(&seckey, 0);
+ curve25519_public_key_generate(&key1, &seckey);
+ tt_int_op(0, ==, curve25519_public_to_base64(buf, &key1));
+ tt_int_op(CURVE25519_BASE64_PADDED_LEN, ==, strlen(buf));
+
+ tt_int_op(0, ==, curve25519_public_from_base64(&key2, buf));
+ test_memeq(key1.public_key, key2.public_key, CURVE25519_PUBKEY_LEN);
+
+ buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0';
+ tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, ==, strlen(buf));
+ tt_int_op(0, ==, curve25519_public_from_base64(&key3, buf));
+ test_memeq(key1.public_key, key3.public_key, CURVE25519_PUBKEY_LEN);
+
+ /* Now try bogus parses. */
+ strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$=", sizeof(buf));
+ tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+ strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", sizeof(buf));
+ tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+ strlcpy(buf, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", sizeof(buf));
+ tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));
+
+ done:
+ ;
+}
+
+static void
+test_crypto_curve25519_persist(void *arg)
+{
+ curve25519_keypair_t keypair, keypair2;
+ char *fname = tor_strdup(get_fname("curve25519_keypair"));
+ char *tag = NULL;
+ char *content = NULL;
+ const char *cp;
+ struct stat st;
+ size_t taglen;
+
+ (void)arg;
+
+ tt_int_op(0,==,curve25519_keypair_generate(&keypair, 0));
+
+ tt_int_op(0,==,curve25519_keypair_write_to_file(&keypair, fname, "testing"));
+ tt_int_op(0,==,curve25519_keypair_read_from_file(&keypair2, &tag, fname));
+ tt_str_op(tag,==,"testing");
+ tor_free(tag);
+
+ test_memeq(keypair.pubkey.public_key,
+ keypair2.pubkey.public_key,
+ CURVE25519_PUBKEY_LEN);
+ test_memeq(keypair.seckey.secret_key,
+ keypair2.seckey.secret_key,
+ CURVE25519_SECKEY_LEN);
+
+ content = read_file_to_str(fname, RFTS_BIN, &st);
+ tt_assert(content);
+ taglen = strlen("== c25519v1: testing ==");
+ tt_u64_op((uint64_t)st.st_size, ==,
+ 32+CURVE25519_PUBKEY_LEN+CURVE25519_SECKEY_LEN);
+ tt_assert(fast_memeq(content, "== c25519v1: testing ==", taglen));
+ tt_assert(tor_mem_is_zero(content+taglen, 32-taglen));
+ cp = content + 32;
+ test_memeq(keypair.seckey.secret_key,
+ cp,
+ CURVE25519_SECKEY_LEN);
+ cp += CURVE25519_SECKEY_LEN;
+ test_memeq(keypair.pubkey.public_key,
+ cp,
+ CURVE25519_SECKEY_LEN);
+
+ tor_free(fname);
+ fname = tor_strdup(get_fname("bogus_keypair"));
+
+ tt_int_op(-1, ==, curve25519_keypair_read_from_file(&keypair2, &tag, fname));
+ tor_free(tag);
+
+ content[69] ^= 0xff;
+ tt_int_op(0, ==, write_bytes_to_file(fname, content, (size_t)st.st_size, 1));
+ tt_int_op(-1, ==, curve25519_keypair_read_from_file(&keypair2, &tag, fname));
+
+ done:
+ tor_free(fname);
+ tor_free(content);
+ tor_free(tag);
+}
+
+#endif
+
+static void
+test_crypto_siphash(void *arg)
+{
+ /* From the reference implementation, taking
+ k = 00 01 02 ... 0f
+ and in = 00; 00 01; 00 01 02; ...
+ */
+ const uint8_t VECTORS[64][8] =
+ {
+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
+ };
+
+ const struct sipkey K = { U64_LITERAL(0x0706050403020100),
+ U64_LITERAL(0x0f0e0d0c0b0a0908) };
+ uint8_t input[64];
+ int i, j;
+
+ (void)arg;
+
+ for (i = 0; i < 64; ++i)
+ input[i] = i;
+
+ for (i = 0; i < 64; ++i) {
+ uint64_t r = siphash24(input, i, &K);
+ for (j = 0; j < 8; ++j) {
+ tt_int_op( (r >> (j*8)) & 0xff, ==, VECTORS[i][j]);
+ }
+ }
+
+ done:
+ ;
+}
+
static void *
pass_data_setup_fn(const struct testcase_t *testcase)
{
@@ -853,11 +1285,23 @@ struct testcase_t crypto_tests[] = {
{ "aes_EVP", test_crypto_aes, TT_FORK, &pass_data, (void*)"evp" },
CRYPTO_LEGACY(sha),
CRYPTO_LEGACY(pk),
+ { "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
+ CRYPTO_LEGACY(digests),
CRYPTO_LEGACY(dh),
CRYPTO_LEGACY(s2k),
{ "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"aes" },
{ "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"evp" },
CRYPTO_LEGACY(base32_decode),
+ { "kdf_TAP", test_crypto_kdf_TAP, 0, NULL, NULL },
+ { "hkdf_sha256", test_crypto_hkdf_sha256, 0, NULL, NULL },
+#ifdef CURVE25519_ENABLED
+ { "curve25519_impl", test_crypto_curve25519_impl, 0, NULL, NULL },
+ { "curve25519_impl_hibit", test_crypto_curve25519_impl, 0, NULL, (void*)"y"},
+ { "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL },
+ { "curve25519_encode", test_crypto_curve25519_encode, 0, NULL, NULL },
+ { "curve25519_persist", test_crypto_curve25519_persist, 0, NULL, NULL },
+#endif
+ { "siphash", test_crypto_siphash, 0, NULL, NULL },
END_OF_TESTCASES
};