aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2019-12-07 18:02:17 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2019-12-16 22:31:17 +0200
commitaf5de2d37e7c2069a3baac85e4341e69f3353a86 (patch)
treeb2aba0ac82d102350ca68e0259d7e4e76c2455a5 /tests
parentb94ecf18bd2bfe558586c461c092ad9d7cdea646 (diff)
downloadlibssh-af5de2d37e7c2069a3baac85e4341e69f3353a86.tar.gz
libssh-af5de2d37e7c2069a3baac85e4341e69f3353a86.tar.xz
libssh-af5de2d37e7c2069a3baac85e4341e69f3353a86.zip
tests: add crypto unittest for chacha20poly1305
v3: - add tests for malformed encrypted inputs v2: - use proper size key for chacha20poly1305 - make copy of cleartext for chacha20poly1305 test-case - update chacha20_encrypted Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/unittests/torture_crypto.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/tests/unittests/torture_crypto.c b/tests/unittests/torture_crypto.c
index fd5e7753..acb70a46 100644
--- a/tests/unittests/torture_crypto.c
+++ b/tests/unittests/torture_crypto.c
@@ -110,10 +110,204 @@ static void torture_crypto_aes256_cbc(void **state)
ssh_cipher_clear(&cipher);
}
+#define POLY1305_TAGLEN 16
+
+uint8_t chacha20poly1305_key[64] =
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
+ "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"
+ "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c"
+ "\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b"
+ "\x3c\x3d\x3e\x3f";
+
+uint8_t chacha20poly1305_cleartext[144] =
+ "\xb4\xfc\x5d\xc2\x49\x8d\x2c\x29\x4a\xc9\x9a\xb0\x1b\xf8\x29"
+ "\xee\x85\x6d\x8c\x04\x34\x7c\x65\xf4\x89\x97\xc5\x71\x70\x41"
+ "\x91\x40\x19\x60\xe1\xf1\x8f\x4d\x8c\x17\x51\xd6\xbc\x69\x6e"
+ "\xf2\x21\x87\x18\x6c\xef\xc4\xf4\xd9\xe6\x1b\x94\xf7\xd8\xb2"
+ "\xe9\x24\xb9\xe7\xe6\x19\xf5\xec\x55\x80\x9a\xc8\x7d\x70\xa3"
+ "\x50\xf8\x03\x10\x35\x49\x9b\x53\x58\xd7\x4c\xfc\x5f\x02\xd6"
+ "\x28\xea\xcc\x43\xee\x5e\x2b\x8a\x7a\x66\xf7\x00\xee\x09\x18"
+ "\x30\x1b\x47\xa2\x16\x69\xc4\x6e\x44\x3f\xbd\xec\x52\xce\xe5"
+ "\x41\xf2\xe0\x04\x4f\x5a\x55\x58\x37\xba\x45\x8d\x15\x53\xf6"
+ "\x31\x91\x13\x8c\x51\xed\x08\x07\xdb";
+
+uint64_t chacha20poly1305_seq = (uint64_t)1234567890 * 98765431;
+
+uint8_t chacha20poly1305_encrypted[sizeof(uint32_t) + 144 + POLY1305_TAGLEN] =
+ "\xac\x2e\x4c\x54\xf6\x97\x75\xb4\x3b\x8f\xb0\x8e\xb0\x0a\x8e"
+ "\xb3\x90\x21\x0d\x7a\xb6\xd3\x03\xf6\xbc\x6e\x3a\x32\x67\xe1"
+ "\x13\x65\x43\x3b\x34\x9d\xcb\x62\x7e\x0a\x80\xb0\x45\x87\x07"
+ "\x85\x49\x8d\x23\x5f\xac\x9c\x8b\xa8\xd5\x01\x12\xfe\x52\xc6"
+ "\x99\xb4\xf2\xde\x12\x78\x79\xea\x1c\x5f\x45\xcd\xf7\xe4\xa0"
+ "\x66\x15\x7f\xe3\xf4\x73\x3b\xe0\x52\xac\x2a\x00\x73\xd0\xd7"
+ "\x95\xa9\xb9\x3a\xe0\x50\x13\xf4\xdc\xfc\x2a\x64\xb5\xcf\x29"
+ "\x88\xef\x4c\x56\x10\x30\x28\xbb\x59\xb8\x23\x58\xab\x01\xa2"
+ "\xab\x6b\xdd\xee\x20\x43\xe1\xec\x7a\xe1\xaa\x8b\x60\x19\xde"
+ "\x3a\xd1\xd6\x80\x49\x7d\x5c\x81\xb8\x96\xad\x62\x32\xe5\x25"
+ "\x72\xe9\x63\x96\xa1\x44\x25\x91\xe1\xdc\x01\xc7\x5c\xa9";
+
+static void torture_crypto_chacha20poly1305(void **state)
+{
+ uint8_t input[sizeof(uint32_t) + sizeof(chacha20poly1305_cleartext)];
+ uint8_t output[sizeof(input) + POLY1305_TAGLEN] = {0};
+ uint8_t *outtag = output + sizeof(input);
+ struct ssh_cipher_struct cipher = {0};
+ uint32_t in_length;
+ int rc;
+ (void)state;
+
+ assert_int_equal(sizeof(output), sizeof(chacha20poly1305_encrypted));
+
+ in_length = htonl(sizeof(chacha20poly1305_cleartext));
+ memcpy(input, &in_length, sizeof(uint32_t));
+ memcpy(input + sizeof(uint32_t), chacha20poly1305_cleartext,
+ sizeof(chacha20poly1305_cleartext));
+
+ rc = get_cipher(&cipher, "chacha20-poly1305@openssh.com");
+ assert_int_equal(rc, SSH_OK);
+
+ assert_int_equal(sizeof(chacha20poly1305_key) * 8, cipher.keysize);
+ assert_non_null(cipher.set_encrypt_key);
+ assert_non_null(cipher.aead_encrypt);
+
+ rc = cipher.set_encrypt_key(&cipher, chacha20poly1305_key, NULL);
+ assert_int_equal(rc, SSH_OK);
+
+ cipher.aead_encrypt(&cipher, input, output, sizeof(input), outtag,
+ chacha20poly1305_seq);
+ assert_memory_equal(output, chacha20poly1305_encrypted,
+ sizeof(chacha20poly1305_encrypted));
+ ssh_cipher_clear(&cipher);
+
+ memset(output, '\0', sizeof(output));
+
+ rc = get_cipher(&cipher, "chacha20-poly1305@openssh.com");
+ assert_int_equal(rc, SSH_OK);
+
+ assert_non_null(cipher.set_decrypt_key);
+ assert_non_null(cipher.aead_decrypt);
+ assert_non_null(cipher.aead_decrypt_length);
+
+ rc = cipher.set_decrypt_key(&cipher, chacha20poly1305_key, NULL);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt_length(&cipher, chacha20poly1305_encrypted,
+ output, sizeof(uint32_t),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt(&cipher, chacha20poly1305_encrypted,
+ output + sizeof(uint32_t), sizeof(cleartext),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_OK);
+
+ assert_memory_equal(output, input, sizeof(input));
+
+ ssh_cipher_clear(&cipher);
+}
+
+static void torture_crypto_chacha20poly1305_bad_packet_length(void **state)
+{
+ uint8_t output[sizeof(uint32_t) + sizeof(chacha20poly1305_cleartext)] = {0};
+ uint8_t encrypted_bad[sizeof(chacha20poly1305_encrypted)];
+ struct ssh_cipher_struct cipher = {0};
+ int rc;
+ (void)state;
+
+ /* Test corrupted packet length */
+ memcpy(encrypted_bad, chacha20poly1305_encrypted, sizeof(encrypted_bad));
+ encrypted_bad[1] ^= 1;
+
+ rc = get_cipher(&cipher, "chacha20-poly1305@openssh.com");
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.set_decrypt_key(&cipher, chacha20poly1305_key, NULL);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt_length(&cipher, encrypted_bad,
+ output, sizeof(uint32_t),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt(&cipher, encrypted_bad,
+ output + sizeof(uint32_t), sizeof(cleartext),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_ERROR);
+
+ ssh_cipher_clear(&cipher);
+}
+
+static void torture_crypto_chacha20poly1305_bad_data(void **state)
+{
+ uint8_t output[sizeof(uint32_t) + sizeof(chacha20poly1305_cleartext)] = {0};
+ uint8_t encrypted_bad[sizeof(chacha20poly1305_encrypted)];
+ struct ssh_cipher_struct cipher = {0};
+ int rc;
+ (void)state;
+
+ /* Test corrupted data */
+ memcpy(encrypted_bad, chacha20poly1305_encrypted, sizeof(encrypted_bad));
+ encrypted_bad[100] ^= 1;
+
+ rc = get_cipher(&cipher, "chacha20-poly1305@openssh.com");
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.set_decrypt_key(&cipher, chacha20poly1305_key, NULL);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt_length(&cipher, encrypted_bad,
+ output, sizeof(uint32_t),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt(&cipher, encrypted_bad,
+ output + sizeof(uint32_t), sizeof(cleartext),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_ERROR);
+
+ ssh_cipher_clear(&cipher);
+}
+
+static void torture_crypto_chacha20poly1305_bad_tag(void **state)
+{
+ uint8_t output[sizeof(uint32_t) + sizeof(chacha20poly1305_cleartext)] = {0};
+ uint8_t encrypted_bad[sizeof(chacha20poly1305_encrypted)];
+ struct ssh_cipher_struct cipher = {0};
+ int rc;
+ (void)state;
+
+ /* Test corrupted tag */
+ assert_int_equal(sizeof(encrypted_bad), sizeof(chacha20poly1305_encrypted));
+ memcpy(encrypted_bad, chacha20poly1305_encrypted, sizeof(encrypted_bad));
+ encrypted_bad[sizeof(encrypted_bad) - 1] ^= 1;
+
+ rc = get_cipher(&cipher, "chacha20-poly1305@openssh.com");
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.set_decrypt_key(&cipher, chacha20poly1305_key, NULL);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt_length(&cipher, encrypted_bad,
+ output, sizeof(uint32_t),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = cipher.aead_decrypt(&cipher, encrypted_bad,
+ output + sizeof(uint32_t), sizeof(cleartext),
+ chacha20poly1305_seq);
+ assert_int_equal(rc, SSH_ERROR);
+
+ ssh_cipher_clear(&cipher);
+}
+
int torture_run_tests(void) {
int rc;
const struct CMUnitTest tests[] = {
cmocka_unit_test(torture_crypto_aes256_cbc),
+ cmocka_unit_test(torture_crypto_chacha20poly1305),
+ cmocka_unit_test(torture_crypto_chacha20poly1305_bad_packet_length),
+ cmocka_unit_test(torture_crypto_chacha20poly1305_bad_data),
+ cmocka_unit_test(torture_crypto_chacha20poly1305_bad_tag),
};
ssh_init();