diff options
| author | 2018-07-28 21:39:42 -0400 | |
|---|---|---|
| committer | 2018-08-01 00:16:54 -0400 | |
| commit | 239a3113e4c6a53a2c7b12e67a0f21afae24b0aa (patch) | |
| tree | 027bc4288f08be240d0b9b2a5f6c6431e76b8b4f /src/core/crypto/aes_util.cpp | |
| parent | Extract mbedtls to cpp file (diff) | |
| download | yuzu-239a3113e4c6a53a2c7b12e67a0f21afae24b0aa.tar.gz yuzu-239a3113e4c6a53a2c7b12e67a0f21afae24b0aa.tar.xz yuzu-239a3113e4c6a53a2c7b12e67a0f21afae24b0aa.zip | |
Make XCI comply to review and style guidelines
Diffstat (limited to 'src/core/crypto/aes_util.cpp')
| -rw-r--r-- | src/core/crypto/aes_util.cpp | 82 |
1 files changed, 45 insertions, 37 deletions
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index a9646e52f..4690af5f8 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp | |||
| @@ -2,58 +2,69 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <mbedtls/cipher.h> | ||
| 5 | #include "core/crypto/aes_util.h" | 6 | #include "core/crypto/aes_util.h" |
| 6 | #include "mbedtls/cipher.h" | 7 | #include "core/crypto/key_manager.h" |
| 7 | 8 | ||
| 8 | namespace Core::Crypto { | 9 | namespace Core::Crypto { |
| 9 | static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), "CTR mode is incorrect."); | ||
| 10 | static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB), "ECB mode is incorrect."); | ||
| 11 | static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS), "XTS mode is incorrect."); | ||
| 12 | 10 | ||
| 13 | template<typename Key, size_t KeySize> | 11 | static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), |
| 14 | Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode) { | 12 | "CTR has incorrect value."); |
| 15 | mbedtls_cipher_init(encryption_context.get()); | 13 | static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB), |
| 16 | mbedtls_cipher_init(decryption_context.get()); | 14 | "ECB has incorrect value."); |
| 15 | static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS), | ||
| 16 | "XTS has incorrect value."); | ||
| 17 | |||
| 18 | // Structure to hide mbedtls types from header file | ||
| 19 | struct CipherContext { | ||
| 20 | mbedtls_cipher_context_t encryption_context; | ||
| 21 | mbedtls_cipher_context_t decryption_context; | ||
| 22 | }; | ||
| 23 | |||
| 24 | template <typename Key, size_t KeySize> | ||
| 25 | Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode) | ||
| 26 | : ctx(std::make_unique<CipherContext>()) { | ||
| 27 | mbedtls_cipher_init(&ctx->encryption_context); | ||
| 28 | mbedtls_cipher_init(&ctx->decryption_context); | ||
| 17 | 29 | ||
| 18 | ASSERT_MSG((mbedtls_cipher_setup( | 30 | ASSERT_MSG((mbedtls_cipher_setup( |
| 19 | encryption_context.get(), | 31 | &ctx->encryption_context, |
| 20 | mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode))) || | 32 | mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode))) || |
| 21 | mbedtls_cipher_setup(decryption_context.get(), | 33 | mbedtls_cipher_setup( |
| 22 | mbedtls_cipher_info_from_type( | 34 | &ctx->decryption_context, |
| 23 | static_cast<mbedtls_cipher_type_t>(mode)))) == 0, | 35 | mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode)))) == 0, |
| 24 | "Failed to initialize mbedtls ciphers."); | 36 | "Failed to initialize mbedtls ciphers."); |
| 25 | 37 | ||
| 26 | ASSERT( | 38 | ASSERT( |
| 27 | !mbedtls_cipher_setkey(encryption_context.get(), key.data(), KeySize * 8, MBEDTLS_ENCRYPT)); | 39 | !mbedtls_cipher_setkey(&ctx->encryption_context, key.data(), KeySize * 8, MBEDTLS_ENCRYPT)); |
| 28 | ASSERT( | 40 | ASSERT( |
| 29 | !mbedtls_cipher_setkey(decryption_context.get(), key.data(), KeySize * 8, MBEDTLS_DECRYPT)); | 41 | !mbedtls_cipher_setkey(&ctx->decryption_context, key.data(), KeySize * 8, MBEDTLS_DECRYPT)); |
| 30 | //"Failed to set key on mbedtls ciphers."); | 42 | //"Failed to set key on mbedtls ciphers."); |
| 31 | } | 43 | } |
| 32 | 44 | ||
| 33 | template<typename Key, size_t KeySize> | 45 | template <typename Key, size_t KeySize> |
| 34 | AESCipher<Key, KeySize>::~AESCipher() { | 46 | AESCipher<Key, KeySize>::~AESCipher() { |
| 35 | mbedtls_cipher_free(encryption_context.get()); | 47 | mbedtls_cipher_free(&ctx->encryption_context); |
| 36 | mbedtls_cipher_free(decryption_context.get()); | 48 | mbedtls_cipher_free(&ctx->decryption_context); |
| 37 | } | 49 | } |
| 38 | 50 | ||
| 39 | template<typename Key, size_t KeySize> | 51 | template <typename Key, size_t KeySize> |
| 40 | void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { | 52 | void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { |
| 41 | ASSERT_MSG((mbedtls_cipher_set_iv(encryption_context.get(), iv.data(), iv.size()) || | 53 | ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) || |
| 42 | mbedtls_cipher_set_iv(decryption_context.get(), iv.data(), iv.size())) == 0, | 54 | mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0, |
| 43 | "Failed to set IV on mbedtls ciphers."); | 55 | "Failed to set IV on mbedtls ciphers."); |
| 44 | } | 56 | } |
| 45 | 57 | ||
| 46 | template<typename Key, size_t KeySize> | 58 | template <typename Key, size_t KeySize> |
| 47 | void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) { | 59 | void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) { |
| 48 | size_t written = 0; | 60 | size_t written = 0; |
| 49 | 61 | ||
| 50 | const auto context = op == Op::Encrypt ? encryption_context.get() : decryption_context.get(); | 62 | const auto context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; |
| 51 | 63 | ||
| 52 | mbedtls_cipher_reset(context); | 64 | mbedtls_cipher_reset(context); |
| 53 | 65 | ||
| 54 | if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { | 66 | if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { |
| 55 | mbedtls_cipher_update(context, src, size, | 67 | mbedtls_cipher_update(context, src, size, dest, &written); |
| 56 | dest, &written); | ||
| 57 | if (written != size) | 68 | if (written != size) |
| 58 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", | 69 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", |
| 59 | size, written); | 70 | size, written); |
| @@ -62,11 +73,9 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op | |||
| 62 | 73 | ||
| 63 | for (size_t offset = 0; offset < size; offset += block_size) { | 74 | for (size_t offset = 0; offset < size; offset += block_size) { |
| 64 | auto length = std::min<size_t>(block_size, size - offset); | 75 | auto length = std::min<size_t>(block_size, size - offset); |
| 65 | mbedtls_cipher_update(context, src + offset, length, | 76 | mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); |
| 66 | dest + offset, &written); | ||
| 67 | if (written != length) | 77 | if (written != length) |
| 68 | LOG_WARNING(Crypto, | 78 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", |
| 69 | "Not all data was decrypted requested={:016X}, actual={:016X}.", | ||
| 70 | length, written); | 79 | length, written); |
| 71 | } | 80 | } |
| 72 | } | 81 | } |
| @@ -74,9 +83,9 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op | |||
| 74 | mbedtls_cipher_finish(context, nullptr, nullptr); | 83 | mbedtls_cipher_finish(context, nullptr, nullptr); |
| 75 | } | 84 | } |
| 76 | 85 | ||
| 77 | template<typename Key, size_t KeySize> | 86 | template <typename Key, size_t KeySize> |
| 78 | void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size, | 87 | void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, |
| 79 | Op op) { | 88 | size_t sector_size, Op op) { |
| 80 | if (size % sector_size > 0) { | 89 | if (size % sector_size > 0) { |
| 81 | LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size."); | 90 | LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size."); |
| 82 | return; | 91 | return; |
| @@ -84,12 +93,11 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, | |||
| 84 | 93 | ||
| 85 | for (size_t i = 0; i < size; i += sector_size) { | 94 | for (size_t i = 0; i < size; i += sector_size) { |
| 86 | SetIV(CalculateNintendoTweak(sector_id++)); | 95 | SetIV(CalculateNintendoTweak(sector_id++)); |
| 87 | Transcode<u8, u8>(src + i, sector_size, | 96 | Transcode<u8, u8>(src + i, sector_size, dest + i, op); |
| 88 | dest + i, op); | ||
| 89 | } | 97 | } |
| 90 | } | 98 | } |
| 91 | 99 | ||
| 92 | template<typename Key, size_t KeySize> | 100 | template <typename Key, size_t KeySize> |
| 93 | std::vector<u8> AESCipher<Key, KeySize>::CalculateNintendoTweak(size_t sector_id) { | 101 | std::vector<u8> AESCipher<Key, KeySize>::CalculateNintendoTweak(size_t sector_id) { |
| 94 | std::vector<u8> out(0x10); | 102 | std::vector<u8> out(0x10); |
| 95 | for (size_t i = 0xF; i <= 0xF; --i) { | 103 | for (size_t i = 0xF; i <= 0xF; --i) { |
| @@ -101,4 +109,4 @@ std::vector<u8> AESCipher<Key, KeySize>::CalculateNintendoTweak(size_t sector_id | |||
| 101 | 109 | ||
| 102 | template class AESCipher<Key128>; | 110 | template class AESCipher<Key128>; |
| 103 | template class AESCipher<Key256>; | 111 | template class AESCipher<Key256>; |
| 104 | } \ No newline at end of file | 112 | } // namespace Core::Crypto \ No newline at end of file |