summaryrefslogtreecommitdiff
path: root/src/core/hw/aes/ccm.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-12 19:36:41 -0500
committerGravatar bunnei2018-01-12 19:36:41 -0500
commit8e51c61dbce925e0992e27c2c33311583645bd6f (patch)
tree2e868c243b15eaa63b953696775e0b84bab2fd22 /src/core/hw/aes/ccm.cpp
parentdynarmic: Update to 83afe435 (diff)
downloadyuzu-8e51c61dbce925e0992e27c2c33311583645bd6f.tar.gz
yuzu-8e51c61dbce925e0992e27c2c33311583645bd6f.tar.xz
yuzu-8e51c61dbce925e0992e27c2c33311583645bd6f.zip
core: Gut out cryptop, since it doesn't compile with C++17.
Diffstat (limited to 'src/core/hw/aes/ccm.cpp')
-rw-r--r--src/core/hw/aes/ccm.cpp77
1 files changed, 5 insertions, 72 deletions
diff --git a/src/core/hw/aes/ccm.cpp b/src/core/hw/aes/ccm.cpp
index dc7035ab6..1ee37aaa4 100644
--- a/src/core/hw/aes/ccm.cpp
+++ b/src/core/hw/aes/ccm.cpp
@@ -3,11 +3,8 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cryptopp/aes.h>
7#include <cryptopp/ccm.h>
8#include <cryptopp/cryptlib.h>
9#include <cryptopp/filters.h>
10#include "common/alignment.h" 6#include "common/alignment.h"
7#include "common/assert.h"
11#include "common/logging/log.h" 8#include "common/logging/log.h"
12#include "core/hw/aes/ccm.h" 9#include "core/hw/aes/ccm.h"
13#include "core/hw/aes/key.h" 10#include "core/hw/aes/key.h"
@@ -15,80 +12,16 @@
15namespace HW { 12namespace HW {
16namespace AES { 13namespace AES {
17 14
18namespace {
19
20// 3DS uses a non-standard AES-CCM algorithm, so we need to derive a sub class from the standard one
21// and override with the non-standard part.
22using CryptoPP::lword;
23using CryptoPP::AES;
24using CryptoPP::CCM_Final;
25using CryptoPP::CCM_Base;
26template <bool T_IsEncryption>
27class CCM_3DSVariant_Final : public CCM_Final<AES, CCM_MAC_SIZE, T_IsEncryption> {
28public:
29 void UncheckedSpecifyDataLengths(lword header_length, lword message_length,
30 lword footer_length) override {
31 // 3DS uses the aligned size to generate B0 for authentication, instead of the original size
32 lword aligned_message_length = Common::AlignUp(message_length, AES_BLOCK_SIZE);
33 CCM_Base::UncheckedSpecifyDataLengths(header_length, aligned_message_length, footer_length);
34 CCM_Base::m_messageLength = message_length; // restore the actual message size
35 }
36};
37
38class CCM_3DSVariant {
39public:
40 using Encryption = CCM_3DSVariant_Final<true>;
41 using Decryption = CCM_3DSVariant_Final<false>;
42};
43
44} // namespace
45
46std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce, 15std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce,
47 size_t slot_id) { 16 size_t slot_id) {
48 if (!IsNormalKeyAvailable(slot_id)) { 17 UNIMPLEMENTED();
49 LOG_ERROR(HW_AES, "Key slot %d not available. Will use zero key.", slot_id); 18 return {};
50 }
51 const AESKey normal = GetNormalKey(slot_id);
52 std::vector<u8> cipher(pdata.size() + CCM_MAC_SIZE);
53
54 try {
55 CCM_3DSVariant::Encryption e;
56 e.SetKeyWithIV(normal.data(), AES_BLOCK_SIZE, nonce.data(), CCM_NONCE_SIZE);
57 e.SpecifyDataLengths(0, pdata.size(), 0);
58 CryptoPP::ArraySource as(pdata.data(), pdata.size(), true,
59 new CryptoPP::AuthenticatedEncryptionFilter(
60 e, new CryptoPP::ArraySink(cipher.data(), cipher.size())));
61 } catch (const CryptoPP::Exception& e) {
62 LOG_ERROR(HW_AES, "FAILED with: %s", e.what());
63 }
64 return cipher;
65} 19}
66 20
67std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce, 21std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce,
68 size_t slot_id) { 22 size_t slot_id) {
69 if (!IsNormalKeyAvailable(slot_id)) { 23 UNIMPLEMENTED();
70 LOG_ERROR(HW_AES, "Key slot %d not available. Will use zero key.", slot_id); 24 return {};
71 }
72 const AESKey normal = GetNormalKey(slot_id);
73 const std::size_t pdata_size = cipher.size() - CCM_MAC_SIZE;
74 std::vector<u8> pdata(pdata_size);
75
76 try {
77 CCM_3DSVariant::Decryption d;
78 d.SetKeyWithIV(normal.data(), AES_BLOCK_SIZE, nonce.data(), CCM_NONCE_SIZE);
79 d.SpecifyDataLengths(0, pdata_size, 0);
80 CryptoPP::AuthenticatedDecryptionFilter df(
81 d, new CryptoPP::ArraySink(pdata.data(), pdata_size));
82 CryptoPP::ArraySource as(cipher.data(), cipher.size(), true, new CryptoPP::Redirector(df));
83 if (!df.GetLastResult()) {
84 LOG_ERROR(HW_AES, "FAILED");
85 return {};
86 }
87 } catch (const CryptoPP::Exception& e) {
88 LOG_ERROR(HW_AES, "FAILED with: %s", e.what());
89 return {};
90 }
91 return pdata;
92} 25}
93 26
94} // namespace AES 27} // namespace AES