diff options
| -rw-r--r-- | src/core/hle/service/nwm/uds_data.cpp | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/src/core/hle/service/nwm/uds_data.cpp b/src/core/hle/service/nwm/uds_data.cpp index 280c73e05..8c6742dba 100644 --- a/src/core/hle/service/nwm/uds_data.cpp +++ b/src/core/hle/service/nwm/uds_data.cpp | |||
| @@ -103,7 +103,8 @@ static std::array<u8, CryptoPP::AES::BLOCKSIZE> GenerateDataCCMPKey( | |||
| 103 | * Generates the Additional Authenticated Data (AAD) for an UDS 802.11 encrypted data frame. | 103 | * Generates the Additional Authenticated Data (AAD) for an UDS 802.11 encrypted data frame. |
| 104 | * @returns a buffer with the bytes of the AAD. | 104 | * @returns a buffer with the bytes of the AAD. |
| 105 | */ | 105 | */ |
| 106 | static std::vector<u8> GenerateCCMPAAD(const MacAddress& sender, const MacAddress& receiver) { | 106 | static std::vector<u8> GenerateCCMPAAD(const MacAddress& sender, const MacAddress& receiver, |
| 107 | const MacAddress& bssid, u16 frame_control) { | ||
| 107 | // Reference: IEEE 802.11-2007 | 108 | // Reference: IEEE 802.11-2007 |
| 108 | 109 | ||
| 109 | // 8.3.3.3.2 Construct AAD (22-30 bytes) | 110 | // 8.3.3.3.2 Construct AAD (22-30 bytes) |
| @@ -113,20 +114,34 @@ static std::vector<u8> GenerateCCMPAAD(const MacAddress& sender, const MacAddres | |||
| 113 | // Control field are masked to 0. | 114 | // Control field are masked to 0. |
| 114 | struct { | 115 | struct { |
| 115 | u16_be FC; // MPDU Frame Control field | 116 | u16_be FC; // MPDU Frame Control field |
| 116 | MacAddress receiver; | 117 | MacAddress A1; |
| 117 | MacAddress transmitter; | 118 | MacAddress A2; |
| 118 | MacAddress destination; | 119 | MacAddress A3; |
| 119 | u16_be SC; // MPDU Sequence Control field | 120 | u16_be SC; // MPDU Sequence Control field |
| 120 | } aad_struct{}; | 121 | } aad_struct{}; |
| 121 | 122 | ||
| 122 | // Default FC value of DataFrame | Protected | ToDS | 123 | constexpr u16 AADFrameControlMask = 0x8FC7; |
| 123 | constexpr u16 DefaultFrameControl = 0x0841; | 124 | aad_struct.FC = frame_control & AADFrameControlMask; |
| 124 | |||
| 125 | aad_struct.FC = DefaultFrameControl; | ||
| 126 | aad_struct.SC = 0; | 125 | aad_struct.SC = 0; |
| 127 | aad_struct.transmitter = sender; | 126 | |
| 128 | aad_struct.receiver = receiver; | 127 | bool to_ds = (frame_control & (1 << 0)) != 0; |
| 129 | aad_struct.destination = receiver; | 128 | bool from_ds = (frame_control & (1 << 1)) != 0; |
| 129 | // In the 802.11 standard, ToDS = 1 and FromDS = 1 is a valid configuration, | ||
| 130 | // however, the 3DS doesn't seem to transmit frames with such combination. | ||
| 131 | ASSERT_MSG(to_ds != from_ds, "Invalid combination"); | ||
| 132 | |||
| 133 | // The meaning of the address fields depends on the ToDS and FromDS fields. | ||
| 134 | if (from_ds) { | ||
| 135 | aad_struct.A1 = receiver; | ||
| 136 | aad_struct.A2 = bssid; | ||
| 137 | aad_struct.A3 = sender; | ||
| 138 | } | ||
| 139 | |||
| 140 | if (to_ds) { | ||
| 141 | aad_struct.A1 = bssid; | ||
| 142 | aad_struct.A2 = sender; | ||
| 143 | aad_struct.A3 = receiver; | ||
| 144 | } | ||
| 130 | 145 | ||
| 131 | std::vector<u8> aad(sizeof(aad_struct)); | 146 | std::vector<u8> aad(sizeof(aad_struct)); |
| 132 | std::memcpy(aad.data(), &aad_struct, sizeof(aad_struct)); | 147 | std::memcpy(aad.data(), &aad_struct, sizeof(aad_struct)); |
| @@ -141,11 +156,12 @@ static std::vector<u8> GenerateCCMPAAD(const MacAddress& sender, const MacAddres | |||
| 141 | static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload, | 156 | static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload, |
| 142 | const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key, | 157 | const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key, |
| 143 | const MacAddress& sender, const MacAddress& receiver, | 158 | const MacAddress& sender, const MacAddress& receiver, |
| 144 | u16 sequence_number) { | 159 | const MacAddress& bssid, u16 sequence_number, |
| 160 | u16 frame_control) { | ||
| 145 | 161 | ||
| 146 | // Reference: IEEE 802.11-2007 | 162 | // Reference: IEEE 802.11-2007 |
| 147 | 163 | ||
| 148 | std::vector<u8> aad = GenerateCCMPAAD(sender, receiver); | 164 | std::vector<u8> aad = GenerateCCMPAAD(sender, receiver, bssid, frame_control); |
| 149 | 165 | ||
| 150 | std::vector<u8> packet_number{0, | 166 | std::vector<u8> packet_number{0, |
| 151 | 0, | 167 | 0, |
| @@ -200,10 +216,11 @@ static std::vector<u8> DecryptDataFrame(const std::vector<u8>& encrypted_payload | |||
| 200 | static std::vector<u8> EncryptDataFrame(const std::vector<u8>& payload, | 216 | static std::vector<u8> EncryptDataFrame(const std::vector<u8>& payload, |
| 201 | const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key, | 217 | const std::array<u8, CryptoPP::AES::BLOCKSIZE>& ccmp_key, |
| 202 | const MacAddress& sender, const MacAddress& receiver, | 218 | const MacAddress& sender, const MacAddress& receiver, |
| 203 | u16 sequence_number) { | 219 | const MacAddress& bssid, u16 sequence_number, |
| 220 | u16 frame_control) { | ||
| 204 | // Reference: IEEE 802.11-2007 | 221 | // Reference: IEEE 802.11-2007 |
| 205 | 222 | ||
| 206 | std::vector<u8> aad = GenerateCCMPAAD(sender, receiver); | 223 | std::vector<u8> aad = GenerateCCMPAAD(sender, receiver, bssid, frame_control); |
| 207 | 224 | ||
| 208 | std::vector<u8> packet_number{0, | 225 | std::vector<u8> packet_number{0, |
| 209 | 0, | 226 | 0, |