From 50b10ef4a5a56a0649ac29d60d16ec7dc8fe2751 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 23 Sep 2020 15:45:45 +0200 Subject: [PATCH] aes_cbc_4k: extend test and run in autopilot - to compare crypted text with host openssl Fixes #3905 --- repos/gems/run/aes_cbc_4k.run | 120 +++++++++++++++++++++++-- repos/gems/src/test/aes_cbc_4k/main.cc | 117 ++++++++++++++++++------ tool/autopilot.list | 1 + 3 files changed, 206 insertions(+), 32 deletions(-) diff --git a/repos/gems/run/aes_cbc_4k.run b/repos/gems/run/aes_cbc_4k.run index cd57f83a69..78e22f428d 100644 --- a/repos/gems/run/aes_cbc_4k.run +++ b/repos/gems/run/aes_cbc_4k.run @@ -1,8 +1,13 @@ +# Block numbers of 0-65535 supported for testing +set block_number 12345 + +set test_rounds 10000 + build "core init test/aes_cbc_4k" create_boot_directory -install_config { +append config { @@ -13,14 +18,119 @@ install_config { - + + + + + + + + + + + } -exec echo -n "Not for the public" > [run_dir]/genode/plaintext -exec echo -n "Better kept private" > [run_dir]/genode/key +install_config $config -build_boot_image "core ld.lib.so spark.lib.so libsparkcrypto.lib.so init test-aes_cbc_4k" +# +# Use host tools to do same aes_cbc_essiv crypto as Genode test will do +# + +set debug_steps 0 + +exec echo -n "Better kept private" > [run_dir]/genode/passphrase +exec echo -n "Not for the public" > [run_dir]/genode/plaintext + +# extent plaintext to 4k to crypt the same size on Genode and here +exec truncate -s 4k [run_dir]/genode/plaintext + +# create some key of right size, e.g. 256 bit +set key_aes [exec sha256sum [run_dir]/genode/passphrase] +# remove file name from output +regexp {([0-9,a-z]+)} $key_aes all key_aes + +if {$debug_steps} { puts "$key_aes - key" } + +# write key +set fd [open [run_dir]/genode/hex_key w] +puts -nonewline $fd $key_aes +close $fd + +# convert key from hex form into binary form +exec xxd -r -p [run_dir]/genode/hex_key [run_dir]/genode/key +if {!$debug_steps} { exec rm [run_dir]/genode/hex_key } + +# +# ESSIV +# + +# hash key +exec sha256sum [run_dir]/genode/key >[run_dir]/genode/hash_of_key + +# read in hash_of_key +set fd [open [run_dir]/genode/hash_of_key r] +set hash_of_key [read $fd] +close $fd +exec rm [run_dir]/genode/hash_of_key + +# extract key from file (contains beside the key also the file name) +regexp {([0-9,a-z]+)} $hash_of_key all hash_of_key + +if {$debug_steps} { puts "$hash_of_key - hash of key" } + +# convert block_number to binary form - up to now works solely for 0-65535 ! +if {$block_number >= 65536} { + puts "block number too large for this script\n" + exit 1 +} +set hex_block [format "%02x%02x" [expr $block_number%256] [expr $block_number/256]] +exec echo "$hex_block" | xxd -r -p >[run_dir]/genode/blocknumber +exec truncate -s 16 [run_dir]/genode/blocknumber + +# crypt the blocknumber with the hash_of_key as key +catch { + # -p - shows information about generated key, salt and iv + exec openssl enc -aes-256-cbc -nosalt -iv 0 -p \ + -K "$hash_of_key" \ + -in [run_dir]/genode/blocknumber \ + -out [run_dir]/genode/iv_crypt +} + +# remove 16 byte at end of this file +exec truncate -s 16 [run_dir]/genode/iv_crypt + +# convert and read in iv in hex form +set iv [exec xxd -p [run_dir]/genode/iv_crypt] + +if {$debug_steps} { puts "$iv - iv" } + +if {!$debug_steps} { + exec rm [run_dir]/genode/blocknumber + exec rm [run_dir]/genode/iv_crypt +} + +# +# Now make aes_cbc with essiv +# + +catch { + exec openssl enc -aes-256-cbc -nosalt -iv "$iv" \ + -K "$key_aes" \ + -in [run_dir]/genode/plaintext \ + -out [run_dir]/genode/openssl_crypted +} + +if {$debug_steps} { exit 0 } + +# +# build and boot image +# +set boot_modules { core ld.lib.so init } +append boot_modules { libc.lib.so vfs.lib.so libcrypto.lib.so test-aes_cbc_4k } + +build_boot_image $boot_modules append qemu_args "-nographic " diff --git a/repos/gems/src/test/aes_cbc_4k/main.cc b/repos/gems/src/test/aes_cbc_4k/main.cc index 8fae71c7c9..2514461cd8 100644 --- a/repos/gems/src/test/aes_cbc_4k/main.cc +++ b/repos/gems/src/test/aes_cbc_4k/main.cc @@ -1,20 +1,22 @@ /* - * \brief Test for using libsparkcrypto + * \brief Test for using aes_cbc_4k * \author Norman Feske + * \author Alexander Boettcher * \date 2018-12-20 */ /* - * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018-2020 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ /* Genode includes */ -#include #include +#include + #include namespace Test { @@ -24,22 +26,39 @@ namespace Test { namespace Genode { - - static inline void print(Output &out, Aes_cbc_4k::Ciphertext const &data) + template + static inline void print_local(Output &out, T const &data, unsigned show_max) { - constexpr unsigned NUM_LINES = 10; constexpr unsigned BYTES_PER_LINE = 32; - for (unsigned line = 0; line < NUM_LINES; line++) { + unsigned rest = sizeof(data.values) < show_max ? sizeof(data.values) : show_max; + unsigned const lines = rest / BYTES_PER_LINE + ((rest % BYTES_PER_LINE == 0) ? 0 : 1); - for (unsigned i = 0; i < BYTES_PER_LINE; i++) + for (unsigned line = 0; line < lines; line++) { + + unsigned const max = rest > BYTES_PER_LINE ? BYTES_PER_LINE : rest; + for (unsigned i = 0; i < max; i++) print(out, Genode::Hex(data.values[line*BYTES_PER_LINE + i], Genode::Hex::OMIT_PREFIX, Genode::Hex::PAD)); - if (line + 1 < NUM_LINES) - print(out, "\n"); + + rest -= max; + if (!rest) break; + + print(out, "\n"); } + if (sizeof(data.values) != show_max) + print(out, "\n..."); } + + static inline void print(Output &out, Aes_cbc_4k::Ciphertext const &data) { + print_local(out, data, sizeof(data.values)); } + + static inline void print(Output &out, Aes_cbc_4k::Plaintext const &data) { + print_local(out, data, sizeof(data.values)); } + + static inline void print(Output &out, Aes_cbc_4k::Key const &data) { + print_local(out, data, sizeof(data.values)); } } @@ -47,44 +66,88 @@ struct Test::Main { Env &_env; - Attached_rom_dataspace _plaintext { _env, "plaintext" }; - Attached_rom_dataspace _key { _env, "key" }; + Attached_rom_dataspace _crypt_extern { _env, "openssl_crypted" }; + Attached_rom_dataspace _plaintext { _env, "plaintext" }; + Attached_rom_dataspace _key { _env, "key" }; Aes_cbc_4k::Ciphertext _ciphertext { }; Aes_cbc_4k::Plaintext _decrypted_plaintext { }; - Main(Env &env) : _env(env) + bool encrypt_decrypt_compare(Aes_cbc_4k::Key const &key, + Aes_cbc_4k::Plaintext const &plaintext, + Aes_cbc_4k::Block_number const &block_number) { - Aes_cbc_4k::Block_number const block_number { 0 }; - - Aes_cbc_4k::Key const &key = *_key.local_addr(); - Aes_cbc_4k::Plaintext const &plaintext = *_plaintext.local_addr(); - Aes_cbc_4k::encrypt(key, block_number, plaintext, _ciphertext); - log("ciphertext:\n", _ciphertext); + if (_crypt_extern.size() < sizeof(_ciphertext.values)) { + error("ciphertext size mismatch: ", + _crypt_extern.size(), " vs ", sizeof(_ciphertext.values)); + return false; + } Aes_cbc_4k::decrypt(key, block_number, _ciphertext, _decrypted_plaintext); /* compare decrypted ciphertext with original plaintext */ if (memcmp(plaintext.values, _decrypted_plaintext.values, sizeof(plaintext))) { + log("plaintext before:\n", plaintext); + log("plaintext after:\n", _decrypted_plaintext); + error("plaintext differs from decrypted ciphertext"); + return false; + } + + return true; + } + + Main(Env &env) : _env(env) + { + Attached_rom_dataspace config(env, "config"); + + Aes_cbc_4k::Block_number block_number { config.xml().attribute_value("block_number", 0U) }; + unsigned const test_rounds { config.xml().attribute_value("test_rounds", 100U) }; + + Aes_cbc_4k::Key const &key = *_key.local_addr(); + Aes_cbc_4k::Plaintext const &plaintext = *_plaintext.local_addr(); + Aes_cbc_4k::Ciphertext const &cryptextern = *_crypt_extern.local_addr(); + + log("block number: ", block_number.value); + log("key: '", key, "'"); + + if (!encrypt_decrypt_compare(key, plaintext, block_number)) + return; + + /* compare ciphertext done by us with external ciphertext */ + if (memcmp(_ciphertext.values, cryptextern.values, sizeof(_ciphertext.values))) { + log("ciphertext by us:\n", _ciphertext); + log("ciphertext by extern:\n", cryptextern); + + error("ciphertext by us differs from external ciphertext"); return; } + /* measure throughput */ + Trace::Timestamp t_start = Trace::timestamp(); + for (unsigned i = 0; i < test_rounds; i++) { + if (!encrypt_decrypt_compare(key, plaintext, block_number)) + return; + block_number.value ++; + } + Trace::Timestamp t_end = Trace::timestamp(); + + if (test_rounds) + log("rounds=", test_rounds, ", cycles=", t_end - t_start, + " cycles/rounds=", (t_end - t_start)/test_rounds); + log("Test succeeded"); } }; -Genode::Env *__genode_env; - - -void Component::construct(Genode::Env &env) +void Libc::Component::construct(Libc::Env &env) { - /* make ada-runtime happy */ - __genode_env = &env; - env.exec_static_constructors(); + Libc::with_libc([&] { - static Test::Main inst(env); + Genode::log("Entry: Libc::Component::construct"); + static Test::Main inst(env); + }); } diff --git a/tool/autopilot.list b/tool/autopilot.list index 5e424229b2..99c45471a1 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -1,3 +1,4 @@ +aes_cbc_4k bomb cpu_bench cpu_quota