From a59b48cffc667c5e25ab8ec3bce951a5d221d086 Mon Sep 17 00:00:00 2001 From: devgianlu Date: Wed, 25 Dec 2024 22:40:50 +0100 Subject: [PATCH] LibCrypto+LibWeb: Replace `RSA_OAEP-EME` implementation This replaces the old `OAEP` implementation with one backed by OpenSSL. The changes also include some added modularity to the RSA class by making the `RSA_EME` and `RSA_EMSE` for encryption/decryption and signing/verifying respectively. --- Libraries/LibCrypto/PK/RSA.cpp | 94 +++----------- Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp | 74 +++++------ Tests/LibCrypto/TestOAEP.cpp | 130 ++----------------- 3 files changed, 60 insertions(+), 238 deletions(-) diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index 002504292ff..8551acadbc5 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -360,79 +360,6 @@ void RSA::import_public_key(ReadonlyBytes bytes, bool pem) m_public_key = maybe_key.release_value().public_key; } -ErrorOr RSA_PKCS1_EME::encrypt(ReadonlyBytes in) -{ - auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8; - dbgln_if(CRYPTO_DEBUG, "key size: {}", mod_len); - if (in.size() > mod_len - 11) - return Error::from_string_literal("Message too long"); - - auto out = TRY(ByteBuffer::create_uninitialized(mod_len)); - - auto ps_length = mod_len - in.size() - 3; - Vector ps; - ps.resize(ps_length); - - fill_with_secure_random(ps); - // since fill_with_random can create zeros (shocking!) - // we have to go through and un-zero the zeros - for (size_t i = 0; i < ps_length; ++i) { - while (!ps[i]) - ps[i] = get_random(); - } - - u8 paddings[] { 0x00, 0x02 }; - - out.overwrite(0, paddings, 2); - out.overwrite(2, ps.data(), ps_length); - out.overwrite(2 + ps_length, paddings, 1); - out.overwrite(3 + ps_length, in.data(), in.size()); - out.trim(3 + ps_length + in.size(), true); // should be a single block - - dbgln_if(CRYPTO_DEBUG, "padded output size: {} buffer size: {}", 3 + ps_length + in.size(), out.size()); - - return TRY(RSA::encrypt(out)); -} - -ErrorOr RSA_PKCS1_EME::decrypt(ReadonlyBytes in) -{ - auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8; - if (in.size() != mod_len) - return Error::from_string_literal("Invalid input size"); - - auto out = TRY(RSA::decrypt(in)); - - if (out.size() < RSA::output_size()) - return Error::from_string_literal("Not enough data after decryption"); - - if (out[0] != 0x00 || out[1] != 0x02) - return Error::from_string_literal("Invalid padding"); - - size_t offset = 2; - while (offset < out.size() && out[offset]) - ++offset; - - if (offset == out.size()) - return Error::from_string_literal("Garbage data, no zero to split padding"); - - ++offset; - - if (offset - 3 < 8) - return Error::from_string_literal("PS too small"); - - return out.slice(offset, out.size() - offset); -} - -ErrorOr RSA_PKCS1_EME::sign(ReadonlyBytes) -{ - return Error::from_string_literal("FIXME: RSA_PKCS_EME::sign"); -} - -ErrorOr RSA_PKCS1_EME::verify(ReadonlyBytes, ReadonlyBytes) -{ - return Error::from_string_literal("FIXME: RSA_PKCS_EME::verify"); -} - ErrorOr hash_kind_to_hash_type(Hash::HashKind hash_kind) { switch (hash_kind) { @@ -455,7 +382,7 @@ ErrorOr hash_kind_to_hash_type(Hash::HashKind hash_kind) } } -ErrorOr RSA_PKCS1_EMSA::verify(ReadonlyBytes message, ReadonlyBytes signature) +ErrorOr RSA_EMSA::verify(ReadonlyBytes message, ReadonlyBytes signature) { auto key = TRY(public_key_to_openssl_pkey(m_public_key)); auto const* hash_type = TRY(hash_kind_to_hash_type(m_hash_kind)); @@ -477,7 +404,7 @@ ErrorOr RSA_PKCS1_EMSA::verify(ReadonlyBytes message, ReadonlyBytes signat VERIFY_NOT_REACHED(); } -ErrorOr RSA_PKCS1_EMSA::sign(ReadonlyBytes message) +ErrorOr RSA_EMSA::sign(ReadonlyBytes message) { auto key = TRY(private_key_to_openssl_pkey(m_private_key)); auto const* hash_type = TRY(hash_kind_to_hash_type(m_hash_kind)); @@ -510,4 +437,21 @@ ErrorOr RSA_PKCS1_EMSA::configure(OpenSSL_PKEY_CTX& ctx) return {}; } +ErrorOr RSA_OAEP_EME::configure(OpenSSL_PKEY_CTX& ctx) +{ + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_padding(ctx.ptr(), RSA_PKCS1_OAEP_PADDING)); + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_oaep_md(ctx.ptr(), TRY(hash_kind_to_hash_type(m_hash_kind)))); + OPENSSL_TRY(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.ptr(), TRY(hash_kind_to_hash_type(m_hash_kind)))); + + if (m_label.has_value() && !m_label->is_empty()) { + // https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/#rsa-parameters + // The library takes ownership of the label so the caller should not free the original memory pointed to by label. + auto* label = OPENSSL_malloc(m_label->size()); + memcpy(label, m_label->data(), m_label->size()); + OPENSSL_TRY(EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.ptr(), label, m_label->size())); + } + + return {}; +} + } diff --git a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp index 39ba8186fca..9ba824203ad 100644 --- a/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp +++ b/Libraries/LibWeb/Crypto/CryptoAlgorithms.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -665,30 +664,27 @@ WebIDL::ExceptionOr> RSAOAEP::encrypt(AlgorithmParams c // 3. Perform the encryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA public key, // the contents of plaintext as the message to be encrypted, M and label as the label, L, and with the hash function specified by the hash attribute // of the [[algorithm]] internal slot of key as the Hash option and MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option. - - auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash)); - ErrorOr maybe_padding = Error::from_string_view(error_message.bytes_as_string_view()); - if (hash == "SHA-1") { - maybe_padding = ::Crypto::Padding::OAEP::eme_encode<::Crypto::Hash::SHA1, ::Crypto::Hash::MGF>(plaintext, label, public_key.length()); - } else if (hash == "SHA-256") { - maybe_padding = ::Crypto::Padding::OAEP::eme_encode<::Crypto::Hash::SHA256, ::Crypto::Hash::MGF>(plaintext, label, public_key.length()); - } else if (hash == "SHA-384") { - maybe_padding = ::Crypto::Padding::OAEP::eme_encode<::Crypto::Hash::SHA384, ::Crypto::Hash::MGF>(plaintext, label, public_key.length()); - } else if (hash == "SHA-512") { - maybe_padding = ::Crypto::Padding::OAEP::eme_encode<::Crypto::Hash::SHA512, ::Crypto::Hash::MGF>(plaintext, label, public_key.length()); - } + Optional<::Crypto::Hash::HashKind> hash_kind = {}; + if (hash == "SHA-1") + hash_kind = ::Crypto::Hash::HashKind::SHA1; + else if (hash == "SHA-256") + hash_kind = ::Crypto::Hash::HashKind::SHA256; + else if (hash == "SHA-384") + hash_kind = ::Crypto::Hash::HashKind::SHA384; + else if (hash == "SHA-512") + hash_kind = ::Crypto::Hash::HashKind::SHA512; // 4. If performing the operation results in an error, then throw an OperationError. - if (maybe_padding.is_error()) { - auto error_message = MUST(String::from_utf8(maybe_padding.error().string_literal())); + if (!hash_kind.has_value()) { + auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash)); return WebIDL::OperationError::create(realm, error_message); } - auto padding = maybe_padding.release_value(); - // 5. Let ciphertext be the value C that results from performing the operation. - auto rsa = ::Crypto::PK::RSA { public_key }; - auto maybe_ciphertext = rsa.encrypt(padding); + auto rsa = ::Crypto::PK::RSA_OAEP_EME { *hash_kind, public_key }; + rsa.set_label(label); + + auto maybe_ciphertext = rsa.encrypt(plaintext); if (maybe_ciphertext.is_error()) return WebIDL::OperationError::create(realm, "Failed to encrypt"_string); @@ -717,36 +713,32 @@ WebIDL::ExceptionOr> RSAOAEP::decrypt(AlgorithmParams c // 3. Perform the decryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA private key, // the contents of ciphertext as the ciphertext to be decrypted, C, and label as the label, L, and with the hash function specified by the hash attribute // of the [[algorithm]] internal slot of key as the Hash option and MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option. - auto rsa = ::Crypto::PK::RSA { private_key }; - u32 private_key_length = private_key.length(); - - auto maybe_padding = rsa.decrypt(ciphertext); - if (maybe_padding.is_error()) - return WebIDL::OperationError::create(realm, "Failed to encrypt"_string); - - auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash)); - ErrorOr maybe_plaintext = Error::from_string_view(error_message.bytes_as_string_view()); - if (hash == "SHA-1") { - maybe_plaintext = ::Crypto::Padding::OAEP::eme_decode<::Crypto::Hash::SHA1, ::Crypto::Hash::MGF>(maybe_padding.release_value(), label, private_key_length); - } else if (hash == "SHA-256") { - maybe_plaintext = ::Crypto::Padding::OAEP::eme_decode<::Crypto::Hash::SHA256, ::Crypto::Hash::MGF>(maybe_padding.release_value(), label, private_key_length); - } else if (hash == "SHA-384") { - maybe_plaintext = ::Crypto::Padding::OAEP::eme_decode<::Crypto::Hash::SHA384, ::Crypto::Hash::MGF>(maybe_padding.release_value(), label, private_key_length); - } else if (hash == "SHA-512") { - maybe_plaintext = ::Crypto::Padding::OAEP::eme_decode<::Crypto::Hash::SHA512, ::Crypto::Hash::MGF>(maybe_padding.release_value(), label, private_key_length); - } + Optional<::Crypto::Hash::HashKind> hash_kind = {}; + if (hash == "SHA-1") + hash_kind = ::Crypto::Hash::HashKind::SHA1; + else if (hash == "SHA-256") + hash_kind = ::Crypto::Hash::HashKind::SHA256; + else if (hash == "SHA-384") + hash_kind = ::Crypto::Hash::HashKind::SHA384; + else if (hash == "SHA-512") + hash_kind = ::Crypto::Hash::HashKind::SHA512; // 4. If performing the operation results in an error, then throw an OperationError. - if (maybe_plaintext.is_error()) { - auto error_message = MUST(String::from_utf8(maybe_plaintext.error().string_literal())); + if (!hash_kind.has_value()) { + auto error_message = MUST(String::formatted("Invalid hash function '{}'", hash)); return WebIDL::OperationError::create(realm, error_message); } // 5. Let plaintext the value M that results from performing the operation. - auto plaintext = maybe_plaintext.release_value(); + auto rsa = ::Crypto::PK::RSA_OAEP_EME { *hash_kind, private_key }; + rsa.set_label(label); + + auto maybe_plaintext = rsa.decrypt(ciphertext); + if (maybe_plaintext.is_error()) + return WebIDL::OperationError::create(realm, "Failed to encrypt"_string); // 6. Return the result of creating an ArrayBuffer containing plaintext. - return JS::ArrayBuffer::create(realm, move(plaintext)); + return JS::ArrayBuffer::create(realm, maybe_plaintext.release_value()); } // https://w3c.github.io/webcrypto/#rsa-oaep-operations diff --git a/Tests/LibCrypto/TestOAEP.cpp b/Tests/LibCrypto/TestOAEP.cpp index 51efe5db95a..3fd2092fb40 100644 --- a/Tests/LibCrypto/TestOAEP.cpp +++ b/Tests/LibCrypto/TestOAEP.cpp @@ -1,138 +1,24 @@ /* * Copyright (c) 2024, stelar7 + * Copyright (c) 2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ #include -#include -#include -#include -#include #include -#include #include // https://www.inf.pucrs.br/~calazans/graduate/TPVLSI_I/RSA-oaep_spec.pdf TEST_CASE(test_oaep) { - u8 message_raw[16] { - 0xd4, 0x36, 0xe9, 0x95, 0x69, 0xfd, 0x32, 0xa7, 0xc8, 0xa0, 0x5b, 0xbc, 0x90, 0xd3, 0x2c, 0x49 - }; - auto message = ReadonlyBytes { message_raw, 16 }; + auto msg = "WellHelloFriendsWellHelloFriendsWellHelloFriendsWellHelloFriends"sv.bytes(); - u8 params_raw[0] {}; - auto params = ReadonlyBytes { params_raw, 0 }; + auto keypair = TRY_OR_FAIL(Crypto::PK::RSA::generate_key_pair(1024)); + auto rsa = Crypto::PK::RSA_OAEP_EME(Crypto::Hash::HashKind::SHA1, keypair); + rsa.set_label("LABEL"sv.bytes()); - u8 expected_raw[127] { - 0xeb, 0x7a, 0x19, 0xac, 0xe9, 0xe3, 0x00, 0x63, - 0x50, 0xe3, 0x29, 0x50, 0x4b, 0x45, 0xe2, 0xca, - 0x82, 0x31, 0x0b, 0x26, 0xdc, 0xd8, 0x7d, 0x5c, - 0x68, 0xf1, 0xee, 0xa8, 0xf5, 0x52, 0x67, 0xc3, - 0x1b, 0x2e, 0x8b, 0xb4, 0x25, 0x1f, 0x84, 0xd7, - 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, - 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, - 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, - 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, - 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, - 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, - 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, - 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, - 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4f, 0x7b, - 0xc2, 0x75, 0x19, 0x52, 0x81, 0xce, 0x32, 0xd2, - 0xf1, 0xb7, 0x6d, 0x4d, 0x35, 0x3e, 0x2d - }; - auto expected = ReadonlyBytes { expected_raw, 127 }; - - u8 seed_data[20] { - 0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34, - 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2, - 0xf0, 0x6c, 0xb5, 0x8f - }; - - auto maybe_result = Crypto::Padding::OAEP::encode( - message, - params, - 127, - [&](auto buffer) { - memcpy(buffer.data(), seed_data, 20); - }); - auto result = maybe_result.release_value(); - - EXPECT_EQ(expected, result); - - u8 n_bytes[128] { - 0xbb, 0xf8, 0x2f, 0x09, 0x06, 0x82, 0xce, 0x9c, 0x23, 0x38, 0xac, 0x2b, 0x9d, 0xa8, 0x71, 0xf7, - 0x36, 0x8d, 0x07, 0xee, 0xd4, 0x10, 0x43, 0xa4, 0x40, 0xd6, 0xb6, 0xf0, 0x74, 0x54, 0xf5, 0x1f, - 0xb8, 0xdf, 0xba, 0xaf, 0x03, 0x5c, 0x02, 0xab, 0x61, 0xea, 0x48, 0xce, 0xeb, 0x6f, 0xcd, 0x48, - 0x76, 0xed, 0x52, 0x0d, 0x60, 0xe1, 0xec, 0x46, 0x19, 0x71, 0x9d, 0x8a, 0x5b, 0x8b, 0x80, 0x7f, - 0xaf, 0xb8, 0xe0, 0xa3, 0xdf, 0xc7, 0x37, 0x72, 0x3e, 0xe6, 0xb4, 0xb7, 0xd9, 0x3a, 0x25, 0x84, - 0xee, 0x6a, 0x64, 0x9d, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xb2, 0x45, 0x45, 0x98, 0x39, 0x4e, - 0xe0, 0xaa, 0xb1, 0x2d, 0x7b, 0x61, 0xa5, 0x1f, 0x52, 0x7a, 0x9a, 0x41, 0xf6, 0xc1, 0x68, 0x7f, - 0xe2, 0x53, 0x72, 0x98, 0xca, 0x2a, 0x8f, 0x59, 0x46, 0xf8, 0xe5, 0xfd, 0x09, 0x1d, 0xbd, 0xcb - }; - - u8 e_bytes[1] { 0x11 }; - - u8 p_bytes[64] { - 0xee, 0xcf, 0xae, 0x81, 0xb1, 0xb9, 0xb3, 0xc9, 0x08, 0x81, 0x0b, 0x10, 0xa1, 0xb5, 0x60, 0x01, - 0x99, 0xeb, 0x9f, 0x44, 0xae, 0xf4, 0xfd, 0xa4, 0x93, 0xb8, 0x1a, 0x9e, 0x3d, 0x84, 0xf6, 0x32, - 0x12, 0x4e, 0xf0, 0x23, 0x6e, 0x5d, 0x1e, 0x3b, 0x7e, 0x28, 0xfa, 0xe7, 0xaa, 0x04, 0x0a, 0x2d, - 0x5b, 0x25, 0x21, 0x76, 0x45, 0x9d, 0x1f, 0x39, 0x75, 0x41, 0xba, 0x2a, 0x58, 0xfb, 0x65, 0x99 - }; - - u8 q_bytes[64] { - 0xc9, 0x7f, 0xb1, 0xf0, 0x27, 0xf4, 0x53, 0xf6, 0x34, 0x12, 0x33, 0xea, 0xaa, 0xd1, 0xd9, 0x35, - 0x3f, 0x6c, 0x42, 0xd0, 0x88, 0x66, 0xb1, 0xd0, 0x5a, 0x0f, 0x20, 0x35, 0x02, 0x8b, 0x9d, 0x86, - 0x98, 0x40, 0xb4, 0x16, 0x66, 0xb4, 0x2e, 0x92, 0xea, 0x0d, 0xa3, 0xb4, 0x32, 0x04, 0xb5, 0xcf, - 0xce, 0x33, 0x52, 0x52, 0x4d, 0x04, 0x16, 0xa5, 0xa4, 0x41, 0xe7, 0x00, 0xaf, 0x46, 0x15, 0x03 - }; - - u8 dp_bytes[64] { - 0x54, 0x49, 0x4c, 0xa6, 0x3e, 0xba, 0x03, 0x37, 0xe4, 0xe2, 0x40, 0x23, 0xfc, 0xd6, 0x9a, 0x5a, - 0xeb, 0x07, 0xdd, 0xdc, 0x01, 0x83, 0xa4, 0xd0, 0xac, 0x9b, 0x54, 0xb0, 0x51, 0xf2, 0xb1, 0x3e, - 0xd9, 0x49, 0x09, 0x75, 0xea, 0xb7, 0x74, 0x14, 0xff, 0x59, 0xc1, 0xf7, 0x69, 0x2e, 0x9a, 0x2e, - 0x20, 0x2b, 0x38, 0xfc, 0x91, 0x0a, 0x47, 0x41, 0x74, 0xad, 0xc9, 0x3c, 0x1f, 0x67, 0xc9, 0x81 - }; - - u8 dq_bytes[64] { - 0x47, 0x1e, 0x02, 0x90, 0xff, 0x0a, 0xf0, 0x75, 0x03, 0x51, 0xb7, 0xf8, 0x78, 0x86, 0x4c, 0xa9, - 0x61, 0xad, 0xbd, 0x3a, 0x8a, 0x7e, 0x99, 0x1c, 0x5c, 0x05, 0x56, 0xa9, 0x4c, 0x31, 0x46, 0xa7, - 0xf9, 0x80, 0x3f, 0x8f, 0x6f, 0x8a, 0xe3, 0x42, 0xe9, 0x31, 0xfd, 0x8a, 0xe4, 0x7a, 0x22, 0x0d, - 0x1b, 0x99, 0xa4, 0x95, 0x84, 0x98, 0x07, 0xfe, 0x39, 0xf9, 0x24, 0x5a, 0x98, 0x36, 0xda, 0x3d - }; - - u8 qinv_bytes[64] { - 0xb0, 0x6c, 0x4f, 0xda, 0xbb, 0x63, 0x01, 0x19, 0x8d, 0x26, 0x5b, 0xdb, 0xae, 0x94, 0x23, 0xb3, - 0x80, 0xf2, 0x71, 0xf7, 0x34, 0x53, 0x88, 0x50, 0x93, 0x07, 0x7f, 0xcd, 0x39, 0xe2, 0x11, 0x9f, - 0xc9, 0x86, 0x32, 0x15, 0x4f, 0x58, 0x83, 0xb1, 0x67, 0xa9, 0x67, 0xbf, 0x40, 0x2b, 0x4e, 0x9e, - 0x2e, 0x0f, 0x96, 0x56, 0xe6, 0x98, 0xea, 0x36, 0x66, 0xed, 0xfb, 0x25, 0x79, 0x80, 0x39, 0xf7 - }; - - u8 expected_rsa_value_bytes[128] { - 0x12, 0x53, 0xe0, 0x4d, 0xc0, 0xa5, 0x39, 0x7b, 0xb4, 0x4a, 0x7a, 0xb8, 0x7e, 0x9b, 0xf2, 0xa0, - 0x39, 0xa3, 0x3d, 0x1e, 0x99, 0x6f, 0xc8, 0x2a, 0x94, 0xcc, 0xd3, 0x00, 0x74, 0xc9, 0x5d, 0xf7, - 0x63, 0x72, 0x20, 0x17, 0x06, 0x9e, 0x52, 0x68, 0xda, 0x5d, 0x1c, 0x0b, 0x4f, 0x87, 0x2c, 0xf6, - 0x53, 0xc1, 0x1d, 0xf8, 0x23, 0x14, 0xa6, 0x79, 0x68, 0xdf, 0xea, 0xe2, 0x8d, 0xef, 0x04, 0xbb, - 0x6d, 0x84, 0xb1, 0xc3, 0x1d, 0x65, 0x4a, 0x19, 0x70, 0xe5, 0x78, 0x3b, 0xd6, 0xeb, 0x96, 0xa0, - 0x24, 0xc2, 0xca, 0x2f, 0x4a, 0x90, 0xfe, 0x9f, 0x2e, 0xf5, 0xc9, 0xc1, 0x40, 0xe5, 0xbb, 0x48, - 0xda, 0x95, 0x36, 0xad, 0x87, 0x00, 0xc8, 0x4f, 0xc9, 0x13, 0x0a, 0xde, 0xa7, 0x4e, 0x55, 0x8d, - 0x51, 0xa7, 0x4d, 0xdf, 0x85, 0xd8, 0xb5, 0x0d, 0xe9, 0x68, 0x38, 0xd6, 0x06, 0x3e, 0x09, 0x55 - }; - - auto expected_rsa_value = ReadonlyBytes { expected_rsa_value_bytes, 128 }; - - auto n = Crypto::UnsignedBigInteger::import_data(n_bytes, 128); - auto e = Crypto::UnsignedBigInteger::import_data(e_bytes, 1); - auto p = Crypto::UnsignedBigInteger::import_data(p_bytes, 64); - auto q = Crypto::UnsignedBigInteger::import_data(q_bytes, 64); - auto dp = Crypto::UnsignedBigInteger::import_data(dp_bytes, 64); - auto dq = Crypto::UnsignedBigInteger::import_data(dq_bytes, 64); - auto qinv = Crypto::UnsignedBigInteger::import_data(qinv_bytes, 64); - auto private_key = Crypto::PK::RSAPrivateKey<>::from_crt(n, e, p, q, dp, dq, qinv); - auto public_key = Crypto::PK::RSAPublicKey(n, e); - auto rsa = Crypto::PK::RSA(public_key, private_key); - - auto enc = TRY_OR_FAIL(rsa.encrypt(result)); - EXPECT_EQ(expected_rsa_value, enc); + auto enc = TRY_OR_FAIL(rsa.encrypt(msg)); + auto dec = TRY_OR_FAIL(rsa.decrypt(enc)); + EXPECT_EQ(msg, dec); }